原生JS实现N级菜单的代码


Posted in Javascript onMay 21, 2017

需求分析

简单的分析一下,要实现N级菜单,首先从布局入手,即判断是否有下级菜单

1.没有下一级菜单,直接排列

2.有下级菜单,又分为下级菜单排放位置,和在上级菜单显示类似 '>' 的符号,效果如图:

原生JS实现N级菜单的代码

图:1

 初步实现

1.实现是否存在   >

注意: 下面凡是担忧 xxx===yyy ? xxx : xxx都是利用三元表达式,来表达思路。

HTML结构如下:

原生JS实现N级菜单的代码

图:2

•要实现图一的效果,我们只需要判断li标签里面的children.length===2 ? 'span存在' : 'span移除'

2.下级菜单出现位置

HTML结构如下:

原生JS实现N级菜单的代码

•实现这一需求,也需要判断children.length===2 ? '上级菜单相对定位, top为0,left为上级的offsetWidth,下级菜单绝对定位' : '不做任何处理'

具体代码即实现

效果图如下:

原生JS实现N级菜单的代码

代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style type="text/css">
    * {
      margin: 0;
      padding: 0;
    }
    #box {
      margin: 200px 0 0 50px;
      text-align: center;
      color: #ccc;
    }
    ul {
      list-style: none;
      float: left;
    }
    li {
      width: 150px;
      height: 40px;
      line-height: 40px;
      background-color: #124520;
      border: 1px solid #eee;
      position: relative;
    }
    li span {
      position: absolute;
      top: 0;
      right: 10px;
    }
    li:hover {
      background-color: #666;
      transition: background-color .5s;
    }
    ul {
      display: none;
    }
    ul.first {
      display: block;
    }
    .relative {
      position:relative;
      top: 0;
      left: 0;
    }
    .absolute {
      position: absolute;
      left: 0;
      top: 0;
    }
    .show {
      display: block;
    }
    .hide {
      display: none;
    }
  </style>
</head>
<body>
  <div id="box">
    <ul class="first">
      <li>一级菜单
        <span>></span>
      </li>
      <li>一级菜单
        <span>></span>
        <ul>
          <li>二级菜单
            <span>></span>
            <ul>
              <li>三级菜单
                <span>></span>
              </li>
              <li>三级菜单
                <span>></span>
              </li>
              <li>三级菜单
                <span>></span>
              </li>
              <li>三级菜单
                <span>></span>
              </li>
            </ul>
          </li>
          <li>二级菜单
            <span>></span>
            <ul>
              <li>三级菜单
                <span>></span>
              </li>
              <li>三级菜单
                <span>></span>
              </li>
              <li>三级菜单
                <span>></span>
              </li>
              <li>三级菜单
                <span>></span>
              </li>
            </ul>
          </li>
          <li>二级菜单
            <span>></span>
          </li>
          <li>二级菜单
            <span>></span>
            <ul>
              <li>三级菜单
                <span>></span>
              </li>
              <li>三级菜单
                <span>></span>
              </li>
              <li>三级菜单
                <span>></span>
              </li>
              <li>三级菜单
                <span>></span>
              </li>
            </ul>
          </li>
        </ul>
      </li>
      <li>一级菜单
        <span>></span>
        <ul>
          <li>二级菜单
            <span>></span>
          </li>
          <li>二级菜单
            <span>></span>
            <ul>
              <li>三级菜单
                <span>></span>
              </li>
              <li>三级菜单
                <span>></span>
              </li>
              <li>三级菜单
                <span>></span>
              </li>
            </ul>
          </li>
          <li>二级菜单
            <span>></span>
            <ul>
              <li>三级菜单
                <span>></span>
              </li>
              <li>三级菜单
                <span>></span>
              </li>
              <li>三级菜单
                <span>></span>
              </li>
              <li>三级菜单
                <span>></span>
              </li>
            </ul>
          </li>
          <li>二级菜单
            <span>></span>
            <ul>
              <li>三级菜单
                <span>></span>
              </li>
              <li>三级菜单
                <span>></span>
              </li>
              <li>三级菜单
                <span>></span>
              </li>
              <li>三级菜单
                <span>></span>
              </li>
            </ul>
          </li>
        </ul>
      </li>
      <li>一级菜单
        <span>></span>
      </li>
    </ul>
  </div>
</body>
<script type="text/javascript">
let uls = document.querySelectorAll("ul"); //获取所有的ul
let lis = document.querySelectorAll("li"); //获取所有的li
let liWidth = document.querySelector("#box ul").offsetWidth-2 //li的宽度 -2是为了好看
/* 布局start */
/*
 * 
 * 通过下面布局中代码实现每个 li.children.length 要么为0 要么为2
 * 0 无下级菜单
 * 2 有下级菜单
 * 
 */
for (let i = uls.length - 1; i >= 0; i--) {
  if(uls[i].parentNode.nodeName === "LI") {
    uls[i].parentNode.classList.add("relative"); //相对定位
    uls[i].classList.add("absolute"); // 绝对定位
    uls[i].style.left = liWidth + "px"; 
  }
}
for (var i = 0; i < lis.length; i++) {
  if( lis[i].children.length === 1) { //没有下一级菜单直接删除
    lis[i].children[0].outerHTML = "";
  };
}
/* 布局end */
for (let i = 0; i < lis.length; i++) { // 控制每一个li
  lis[i].onmouseover = function() {
    if( lis[i].children.length === 2) {
      this.children[1].classList.remove("hide");
      this.children[1].classList.add("show");
    } 
  }
  lis[i].onmouseout = function() {
    if( lis[i].children.length === 2) {
      this.children[1].classList.remove("show");
      this.children[1].classList.add("hide");
    }
  }
}
</script>
</html>

以上所述是小编给大家介绍的原生JS实现N级菜单的代码,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

Javascript 相关文章推荐
Javascript引用指针使用介绍
Nov 07 Javascript
javascript 中String.match()与RegExp.exec()的区别说明
Jan 10 Javascript
JavaScript NodeTree导航栏(菜单项JSON类型/自制)
Feb 01 Javascript
JS实现的5级联动Select下拉选择框实例
Aug 17 Javascript
JS将滑动门改为选项卡(需鼠标点击)的实现方法
Sep 27 Javascript
jQuery表格行上移下移和置顶的实现方法
Oct 08 Javascript
深入浅析Vue不同场景下组件间的数据交流
Aug 15 Javascript
JS解决IOS中拍照图片预览旋转90度BUG的问题
Sep 13 Javascript
js实现HTML中Select二级联动的实例
Jan 05 Javascript
Angularjs实现页面模板清除的方法
Jul 20 Javascript
Vue2.0+Vux搭建一个完整的移动webApp项目的示例
Mar 19 Javascript
node.js如何自定义实现一个EventEmitter
Jul 16 Javascript
Ionic + Angular.js实现图片轮播的方法示例
May 21 #Javascript
详解Angular2中Input和Output用法及示例
May 21 #Javascript
Angular2中如何使用ngx-translate进行国际化
May 21 #Javascript
详解angularjs利用ui-route异步加载组件
May 21 #Javascript
如何在AngularJs中调用第三方插件库
May 21 #Javascript
详解Angular-Cli中引用第三方库
May 21 #Javascript
Angular2安装angular-cli
May 21 #Javascript
You might like
用Flash图形化数据(二)
2006/10/09 PHP
WordPress中编写自定义存储字段的相关PHP函数解析
2015/12/25 PHP
浅谈php中fopen不能创建中文文件名文件的问题
2017/02/06 PHP
php微信公众号开发之翻页查询
2018/10/20 PHP
jquery解决图片路径不存在执行替换路径
2013/02/06 Javascript
Javascript call和apply区别及使用方法
2013/11/14 Javascript
网页广告中JS代码的信息监听示例
2014/04/02 Javascript
JavaScript AJAX之惰性载入函数
2014/08/27 Javascript
javascript trim函数在IE下不能用的解决方法
2014/09/12 Javascript
javascript面向对象之this关键词用法分析
2015/01/13 Javascript
JavaScript监听和禁用浏览器回车事件实例
2015/01/31 Javascript
jQuery向后台传入json格式数据的方法
2015/02/13 Javascript
JavaScript中使用Math.PI圆周率属性的方法
2015/06/14 Javascript
jquery 全选、全不选、反选效果的实现代码【推荐】
2016/05/05 Javascript
Bootstrap 实现查询的完美方法
2016/10/26 Javascript
jQuery ajax的功能实现方法详解
2017/01/06 Javascript
JavaScript实现图片切换效果
2017/08/12 Javascript
Vue 实现一个命令式弹窗组件功能
2019/09/25 Javascript
关于ligerui子页面关闭后,父页面刷新,重新加载的方法
2019/09/27 Javascript
vue中对象数组去重的实现
2020/02/06 Javascript
解决vuex数据页面刷新后初始化操作
2020/07/26 Javascript
js实现简易ATM功能
2020/10/27 Javascript
[01:21]DOTA2 新英雄 森海飞霞
2020/12/18 DOTA
使用Pyrex来扩展和加速Python程序的教程
2015/04/13 Python
深入理解Python中字典的键的使用
2015/08/19 Python
Python将DataFrame的某一列作为index的方法
2018/04/08 Python
浅谈Python traceback的优雅处理
2018/08/31 Python
Python使用random.shuffle()打乱列表顺序的方法
2018/11/08 Python
Python实现的合并两个有序数组算法示例
2019/03/04 Python
python爬取音频下载的示例代码
2020/10/19 Python
美体小铺瑞典官方网站:The Body Shop瑞典
2018/01/27 全球购物
个人四风对照检查材料
2014/09/26 职场文书
财务总监岗位职责范本
2015/04/03 职场文书
政审证明材料
2015/06/19 职场文书
幼儿园开学家长寄语(2016春季)
2015/12/03 职场文书
css实现两栏布局,左侧固定宽,右侧自适应的多种方法
2021/08/07 HTML / CSS