通知
此博客运行在jpress系统上,如果你喜欢此博客模板,请加QQ群:1061691290(whimurmur模板/jpress插件),免费下载使用

html+css+jquery实现多级菜单(二级及以上)

1090人浏览 / 0人评论 | 作者:whisper  | 分类: html  | 标签: html  | 

作者: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代码,最后得到一个完整的多级菜单代码段,插入到文档中。


亲爱的读者:有时间可以点赞评论一下

点赞(0) 打赏

全部评论

还没有评论!