作者:whisper
链接:http://proprogrammar.com:443/article/576
声明:请尊重原作者的劳动,如需转载请注明出处
自己的这个博客内容越来越多,原来的二级菜单有点不够用了,原来用的模板只支持二级菜单,而且有些个人的原因想换一个模板,所以就使用了自带的一个模板,这个模板界面没有原来的好看,但基本功能还算齐全,但是只支持一级菜单,所以自己就动手找了一个二级菜单的例子,然后动手改了改,改成了可以支持四级的菜单,博客模板是用的模板引擎,不是常见的css+html+javascript组合的形式,所以就不用模板中的代码了,使用自己修改的找的二级菜单的代码。
下面先看一下效果(五级菜单)
可以看到二级菜单有下级菜单时上级菜单的文字后带">",点击上级菜单,出现下级菜单,上级菜单文字变成"返回上级<",点击"返回上级<",会回到上级菜单,多级菜单可以嵌套,菜单出现或消失时有特效
看一下html代码
<div class="test2Body">
<nav>
<ul class="closeFloat">
<li><a>菜单一</a>
<ul>
<li><a>二级菜单1</a></li>
<li><a>二级菜单2</a></li>
<li><a>二级菜单3</a></li>
</ul>
</li>
<li>菜单二</li>
<li><a>菜单三</a>
<ul>
<li><a>二级菜单4</a></li>
<li data-menu="二级菜单5>"><a>二级菜单5></a>
<ul>
<li><a>三级菜单1</a></li>
<li><a>三级菜单2</a></li>
<li><a>三级菜单3</a></li>
<li><a>三级菜单4</a></li>
<li><a>三级菜单5</a></li>
</ul>
</li>
<li><a>二级菜单6</a></li>
<li data-menu="子级菜单7>"><a>二级菜单7></a>
<ul>
<li><a>三级菜单6</a></li>
<li><a>三级菜单7</a></li>
<li><a>三级菜单8</a></li>
<li data-menu="三级菜单9>"><a>三级菜单9></a>
<ul>
<li><a>四级菜单1</a></li>
<li><a>四级菜单2</a></li>
<li data-menu="四级菜单3>"><a>四级菜单3></a>
<ul>
<li><a>五级菜单1</a></li>
<li><a>五级菜单2</a></li>
<li><a>五级菜单3</a></li>
<li><a>五级菜单4</a></li>
<li><a>五级菜单5</a></li>
</ul>
</li>
<li data-menu="四级菜单4>"><a>四级菜单4></a>
<ul>
<li><a>五级菜单6</a></li>
<li><a>五级菜单7</a></li>
<li><a>五级菜单8</a></li>
<li><a>五级菜单9</a></li>
<li><a>五级菜单10</a></li>
</ul>
</li>
<li><a>四级菜单5</a></li>
</ul>
</li>
<li><a>三级菜单10</a></li>
</ul>
</li>
<li><a>二级菜单8</a></li>
</ul>
</li>
<li><a>菜单四</a></li>
<li><a>菜单五</a></li>
</ul>
</nav>
</div>
可以看出代码很简单div里面有个nav(非必须),然后就是ul,li嵌套构成菜单,li要有一个data-menu属性存储菜单的名字,当从"返回上级<"返回时获取原来的菜单名,li下有一个a标签,如果有子菜单,那还有ul子元素存子菜单
再看一下css代码
*{
padding: 0;
margin: 0;
}
ol,ul,li{
list-style: none;
padding-inline-start: 0;
}
.test2Body{
width: 80%;
margin: 0 auto;
}
.testBottom{
background-color: aquamarine;
}
.test2Body>nav>ul{
width: 100%;
background-color: dodgerblue;
text-align: center;
font-size: 14px;
}
/* 一级菜单绝对定位 */
.test2Body>nav>ul>li{
position: relative;
float: left;
line-height: 50px;
width: 20%;
box-sizing: border-box;
}
/* 子菜单hover效果 */
.test2Body>nav>ul li:hover{
color: white;
background-color: rgba(255,255,255,0.5);
}
/* 二级菜单不显示,绝对定位 */
.test2Body>nav>ul>li>ul{
display: none;
position: absolute;
width: 100%;
z-index: 100;
background-color: dodgerblue;
}
/* 三级及以上菜单不显示 */
.test2Body>nav>ul>li>ul ul{
display: none;
width: 100%;
z-index: 100;
background-color: dodgerblue;
}
/* 下面是动画 */
.test2Body>nav>ul>li ul>li{
display: inline-block;
width: 100%;
background-color: rgba(255,255,255,0.5);
animation-name: navAnim;
}
.test2Body>nav>ul>li ul>li:nth-of-type(3n+1){
animation-duration: 0.25s;
}
.test2Body>nav>ul>li ul>li:nth-of-type(3n+2){
animation-duration: 0.5s;
}
.test2Body>nav>ul>li ul>li:nth-of-type(3n){
animation-duration: 0.75s;
}
.test2Body>nav>ul>li ul>li:hover{
color: white;
background-color: rgba(255,255,255,0);
}
@keyframes navAnim
{
0%{transform: rotateY(180deg)}
50%{transform: rotateY(90deg)}
100%{transform: rotateY(0deg)}
}
/* 下面用来清除浮动 */
.closeFloat:after{display:block;clear:both;content:"";visibility:hidden;height:0}
.closeFloat{zoom:1}
解释在代码里,代码没怎么优化
最后看一下jquery代码
<script type="text/javascript">
// hover一级菜单
$("nav>ul>li").hover(function(){
// 进入一级菜单时显示二级菜单
$(this).children("ul").css("display", "block");
},function(){
// 离开一级菜单时所有子菜单隐藏,所有"返回上级<"变成原来的菜单文字
$("nav>ul>li ul").css("display", "none");
$("nav>ul>li li").each(function(){
if($(this).children("a").text() == "返回上级<"){
$(this).children("a").text($(this).attr("data-menu"));
}
});
});
// 点击下级菜单时
$("nav>ul>li ul>li").click(function(){
// 如果点击返回上级<,隐藏所有下级菜单,恢复上级菜单文字,同时将下级菜单中所有的返回上级<变成原来的菜单文字
if($(this).children("a").text() == "返回上级<"){
$(this).find("ul").slideUp();
$(this).children("a").text($(this).attr("data-menu"));
$(this).find("li").each(function(){
if($(this).children("a").text() == "返回上级<"){
$(this).children("a").text($(this).attr("data-menu"));
}
});
// 如果点击的菜单有子菜单,而且子菜单没展开,展开子菜单,同时菜单文字变成返回上级<
}else if($(this).children("ul").length){
$(this).children("ul").css("display", "block");
$(this).children("a").text("返回上级<");
//$(this).closest("ul").css("display", "none");
}else{
// 普通的子菜单(不存在子菜单),打开相关页面
if($(this).children("a").attr("target") == "_blank"){
window.open($(this).children("a").attr("href"));
}else{
window.location.href = $(this).children("a").attr("href");
}
}
// 阻止冒泡
return false;
});
</script>
利用jquery方便的操作dom,解释在代码中,记得引入jquery文件
下面的完整的代码
<html>
<head>
<meta charset="UTF-8">
<title>菜单栏</title>
<script src="jquery-3.2.1.min.js" type="text/javascript"></script>
<style>
*{
padding: 0;
margin: 0;
}
ol,ul,li{
list-style: none;
padding-inline-start: 0;
}
.test2Body{
width: 80%;
margin: 0 auto;
}
.testBottom{
background-color: aquamarine;
}
.test2Body>nav>ul{
width: 100%;
background-color: dodgerblue;
text-align: center;
font-size: 14px;
}
.test2Body>nav>ul>li{
position: relative;
float: left;
line-height: 50px;
width: 20%;
box-sizing: border-box;
}
.test2Body>nav>ul li:hover{
color: white;
background-color: rgba(255,255,255,0.5);
}
/* .test2Body>nav>ul>li:hover>ul{
display: block;
}*/
.test2Body>nav>ul>li>ul{
display: none;
position: absolute;
width: 100%;
z-index: 100;
background-color: dodgerblue;
}
.test2Body>nav>ul>li>ul ul{
display: none;
width: 100%;
z-index: 100;
background-color: dodgerblue;
}
.test2Body>nav>ul>li ul>li{
display: inline-block;
width: 100%;
background-color: rgba(255,255,255,0.5);
animation-name: navAnim;
}
.test2Body>nav>ul>li ul>li:nth-of-type(3n+1){
animation-duration: 0.25s;
}
.test2Body>nav>ul>li ul>li:nth-of-type(3n+2){
animation-duration: 0.5s;
}
.test2Body>nav>ul>li ul>li:nth-of-type(3n){
animation-duration: 0.75s;
}
.test2Body>nav>ul>li ul>li:hover{
color: white;
background-color: rgba(255,255,255,0);
}
@keyframes navAnim
{
0%{transform: rotateY(180deg)}
50%{transform: rotateY(90deg)}
100%{transform: rotateY(0deg)}
}
.closeFloat:after{display:block;clear:both;content:"";visibility:hidden;height:0}
.closeFloat{zoom:1}
</style>
</head>
<body>
<div class="test2Body">
<nav>
<ul class="closeFloat">
<li><a>菜单一</a>
<ul>
<li><a>二级菜单1</a></li>
<li><a>二级菜单2</a></li>
<li><a>二级菜单3</a></li>
</ul>
</li>
<li>菜单二</li>
<li><a>菜单三</a>
<ul>
<li><a>二级菜单4</a></li>
<li data-menu="二级菜单5>"><a>二级菜单5></a>
<ul>
<li><a>三级菜单1</a></li>
<li><a>三级菜单2</a></li>
<li><a>三级菜单3</a></li>
<li><a>三级菜单4</a></li>
<li><a>三级菜单5</a></li>
</ul>
</li>
<li><a>二级菜单6</a></li>
<li data-menu="子级菜单7>"><a>二级菜单7></a>
<ul>
<li><a>三级菜单6</a></li>
<li><a>三级菜单7</a></li>
<li><a>三级菜单8</a></li>
<li data-menu="三级菜单9>"><a>三级菜单9></a>
<ul>
<li><a>四级菜单1</a></li>
<li><a>四级菜单2</a></li>
<li data-menu="四级菜单3>"><a>四级菜单3></a>
<ul>
<li><a>五级菜单1</a></li>
<li><a>五级菜单2</a></li>
<li><a>五级菜单3</a></li>
<li><a>五级菜单4</a></li>
<li><a>五级菜单5</a></li>
</ul>
</li>
<li data-menu="四级菜单4>"><a>四级菜单4></a>
<ul>
<li><a>五级菜单6</a></li>
<li><a>五级菜单7</a></li>
<li><a>五级菜单8</a></li>
<li><a>五级菜单9</a></li>
<li><a>五级菜单10</a></li>
</ul>
</li>
<li><a>四级菜单5</a></li>
</ul>
</li>
<li><a>三级菜单10</a></li>
</ul>
</li>
<li><a>二级菜单8</a></li>
</ul>
</li>
<li><a>菜单四</a></li>
<li><a>菜单五</a></li>
</ul>
</nav>
</div>
<script type="text/javascript">
// hover一级菜单
$("nav>ul>li").hover(function(){
// 进入一级菜单时显示二级菜单
$(this).children("ul").css("display", "block");
},function(){
// 离开一级菜单时所有子菜单隐藏,所有"返回上级<"变成原来的菜单文字
$("nav>ul>li ul").css("display", "none");
$("nav>ul>li li").each(function(){
if($(this).children("a").text() == "返回上级<"){
$(this).children("a").text($(this).attr("data-menu"));
}
});
});
// 点击下级菜单时
$("nav>ul>li ul>li").click(function(){
// 如果点击返回上级<,隐藏所有下级菜单,恢复上级菜单文字,同时将下级菜单中所有的返回上级<变成原来的菜单文字
if($(this).children("a").text() == "返回上级<"){
$(this).find("ul").slideUp();
$(this).children("a").text($(this).attr("data-menu"));
$(this).find("li").each(function(){
if($(this).children("a").text() == "返回上级<"){
$(this).children("a").text($(this).attr("data-menu"));
}
});
// 如果点击的菜单有子菜单,而且子菜单没展开,展开子菜单,同时菜单文字变成返回上级<
}else if($(this).children("ul").length){
$(this).children("ul").css("display", "block");
$(this).children("a").text("返回上级<");
//$(this).closest("ul").css("display", "none");
}else{
// 普通的子菜单(不存在子菜单),打开相关页面
if($(this).children("a").attr("target") == "_blank"){
window.open($(this).children("a").attr("href"));
}else{
window.location.href = $(this).children("a").attr("href");
}
}
// 阻止冒泡
return false;
});
</script>
</body>
</html>
上面的菜单是直接写死在代码中的,实际中可能是从服务器获取的,而且菜单的级数是不固定的,这时可以利用一个递归函数(深度优先处理)来拼接菜单的html代码,最后得到一个完整的多级菜单代码段,插入到文档中。
亲爱的读者:有时间可以点赞评论一下
全部评论