Javascript小案例--树形菜单(菜单数据为对象)

理论上菜单层级可以无限多,因为是递归渲染。
gif效果图:

代码

DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>树形菜单title>
head>
<style>
  * {
    padding: 0;
    margin: 0;
    box-sizing: border-box;
    font-size: 14px;
  }

  body{
    background-color: #444;
  }
  /*侧栏菜单 */
  .aside_menu {
    position: fixed;
    min-width: 350px;
    height: 700px;
    background-color: #333;
    padding: 20px;
    border: 0;
    border-right: 3px solid #333;
    cursor: pointer;
    color: white;
    overflow: auto;
  }

  /* 菜单项 */
  .menuItem{
    margin-bottom: 5px;
    height: 30px;
    line-height: 30px;
    padding-right: 10px;
  }  
  .menuItem:hover {
    color: #333;
    background-color: #bbcaca;
  }

  /* 有子菜单的菜单项 */
  [data-child-count]::after {
    content: '<';
    opacity: 0.3;
    float: right;
  }

  /* 有子菜单的菜单项 */
  .expandable::after {
    content: '>';
    opacity: 0.3;
    float: right;
  }

  /* 子菜单折叠 */
  .collapsable {
    display: none;
  }
style>

<body>
  <div class="aside_menu">
    <div class="menuwrraper">div>
  div>
  <script>
    /**
     * 菜单对象说明:
      {
        id: '0',//菜单id
        name: '菜单名',//菜单名称
        submenu: []//子菜单集合
      },
     **/
    let menuRoot = {
      id: '0',
      name: '树形菜单',
      submenu: [
        {
          id: '0',
          name: '菜单',
          submenu: []
        },
        {
          id: '0',
          name: '菜单',
          submenu: [
            {
              id: '0',
              name: '菜单',
              submenu: [
                {
                  id: '0',
                  name: '菜单',
                  submenu: []
                },
              ]
            },
          ]
        },
        {
          id: '0',
          name: '菜单',
          submenu: [
            {
              id: '0',
              name: '菜单',
              submenu: []
            },
          ]
        },
        {
          id: '0',
          name: '菜单',
          submenu: [
            {
              id: '0',
              name: '菜单',
              submenu: [
                {
                  id: '0',
                  name: '菜单',
                  submenu: [
                    {
                      id: '0',
                      name: '菜单',
                      submenu: [
                        {
                          id: '0',
                          name: '菜单',
                          submenu: [
                            {
                              id: '0',
                              name: '菜单',
                              submenu: [
                                {
                                  id: '0',
                                  name: '菜单',
                                  submenu: [
                                    {
                                      id: '0',
                                      name: '菜单',
                                      submenu: [
                                        {
                                          id: '0',
                                          name: '菜单',
                                          submenu: [
                                            {
                                              id: '0',
                                              name: '菜单',
                                              submenu: [
                                                {
                                                  id: '0',
                                                  name: '菜单',
                                                  submenu: []
                                                },
                                              ]
                                            },
                                          ]
                                        },
                                      ]
                                    },
                                  ]
                                },
                              ]
                            },
                          ]
                        },
                      ]
                    },
                  ]
                },
              ]
            },
          ]
        },
        {
          id: '0',
          name: '菜单',
          submenu: [
            {
              id: '0',
              name: '菜单',
              submenu: [
                {
                  id: '0',
                  name: '菜单',
                  submenu: [
                    {
                      id: '0',
                      name: '菜单',
                      submenu: [
                        {
                          id: '0',
                          name: '菜单',
                          submenu: [
                            {
                              id: '0',
                              name: '菜单',
                              submenu: [
                                {
                                  id: '0',
                                  name: '菜单',
                                  submenu: [
                                    {
                                      id: '0',
                                      name: '菜单',
                                      submenu: [
                                        {
                                          id: '0',
                                          name: '菜单',
                                          submenu: [
                                            {
                                              id: '0',
                                              name: '菜单',
                                              submenu: [
                                                {
                                                  id: '0',
                                                  name: '菜单',
                                                  submenu: []
                                                },
                                              ]
                                            },
                                          ]
                                        },
                                      ]
                                    },
                                  ]
                                },
                              ]
                            },
                          ]
                        },
                      ]
                    },
                  ]
                },
              ]
            },
          ]
        },
        {
          id: '0',
          name: '菜单',
          submenu: [
            {
              id: '0',
              name: '菜单',
              submenu: [
                {
                  id: '0',
                  name: '菜单',
                  submenu: [
                    {
                      id: '0',
                      name: '菜单',
                      submenu: [
                        {
                          id: '0',
                          name: '菜单',
                          submenu: [
                            {
                              id: '0',
                              name: '菜单',
                              submenu: [
                                {
                                  id: '0',
                                  name: '菜单',
                                  submenu: [
                                    {
                                      id: '0',
                                      name: '菜单',
                                      submenu: [
                                        {
                                          id: '0',
                                          name: '菜单',
                                          submenu: [
                                            {
                                              id: '0',
                                              name: '菜单',
                                              submenu: [
                                                {
                                                  id: '0',
                                                  name: '菜单',
                                                  submenu: []
                                                },
                                              ]
                                            },
                                          ]
                                        },
                                      ]
                                    },
                                  ]
                                },
                              ]
                            },
                          ]
                        },
                      ]
                    },
                  ]
                },
              ]
            },
          ]
        },
      ]
    }
    /**
     * menuWrraper-菜单最外层包装盒子,用于包裹当前菜单项及当前菜单项的子菜单
     * level-菜单层级,默认为L0,依次为L1,L2,...
     * menuData-菜单对象
     * paddingLeft-菜单左内边距,会根据菜单层级Level依次增加paddingIncrement
     * paddingIncrement-默认为20,单位为 px
     * */
    function renderMenu(menuData, menuWrraper, level = 0, paddingLeft = 0, paddingIncrement = 20) {
      if (menuData != null) {
        // 0.创建当前菜单
        const menuItem = document.createElement('div')
        // 0.1 添加菜单id
        menuItem.dataset.id = menuData.id
        // 0.2 添加菜单层级L0,L1,L2,...
        menuItem.classList.add(`L${level}`)
        // 0.3 用于控制鼠标 hover效果
        menuItem.classList.add('menuItem')
        // 0.4 菜单左内边距
        menuItem.style.paddingLeft = `${paddingLeft}px`
        // 0.5 菜单内容
        menuItem.innerHTML = `${menuData.name}`
        // 0.6 ****追加当前菜单盒子
        menuWrraper.appendChild(menuItem)
        const submenu = menuData.submenu
        if (submenu.length > 0) {// 如果当前菜单有子菜单,则
          // 1. 为当前菜单追加一个属性,表示其有 子菜单
          // menuItem.dataset.hasChild = 1
          menuItem.dataset.childCount = submenu.length
          // 2. 为当前菜单注册点击事件,可折叠展开子菜单、切换折叠展开图标
          menuItem.addEventListener('click', () => {
            // 2.1 ****用于CSS渲染可展开的最右侧小图标:‘<’ 或者 ‘>’
            menuItem.classList.toggle('expandable')
            // 2.2 ****用于控制子菜单折叠与展开,也即控制submenuWrraper的dispaly属性为‘none’或者‘block’
            menuItem.nextElementSibling.classList.toggle('collapsable')
          })
          // 3. 菜单层级加1
          level++;
          // 4. 左边距增加
          paddingLeft += paddingIncrement
          // 5. 创建子菜单包装盒子
          const submenuWrraper = document.createElement('div')
          // 7.*****追加子菜单盒子,追加这个盒子的原因是 2.2
          menuWrraper.appendChild(submenuWrraper)
          // 6.*****循环当前菜单的子菜单
          for (let i = 0; i < submenu.length; i++) {
            // 6.1 ****递归渲染每一项子菜单
            renderMenu(submenu[i], submenuWrraper, level, paddingLeft)
          }
          
        }
      }
    }
    // 调用菜单渲染函数生成页面数据
    renderMenu(menuRoot, document.querySelector('.menuwrraper'))
    // 渲染完毕后,释放菜单数据
    menuRoot = null
  script>
body>

html>

你可能感兴趣的:(Javascript,JavaScript,html,css,树形菜单)