You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

点击嵌套子菜单时防止父级<li>菜单关闭的解决方案咨询

点击嵌套子菜单时防止父级
  • 菜单关闭的解决方案咨询
  • 嘿,各位大佬!我最近在开发一个三层嵌套导航菜单时碰到了个小麻烦,希望能得到社区朋友们的思路点拨,帮我这个同行开发者理清头绪。下面是详细情况:

    一、当前实现的基础设置

    • 基于jQuery实现的三层菜单,通过点击事件控制第二、第三层级菜单的显示/隐藏
    • 已实现的功能:
      • 点击主菜单(一级)带子菜单的项时,能正常展开/收起对应的二级子菜单
      • 打开某个主菜单的二级子菜单时,会自动关闭其他所有展开的二级子菜单

    二、遇到的问题

    我给菜单和子菜单项都绑定了点击事件,但点击带有三级子菜单的二级菜单项时,它的父级主菜单(一级)会被关闭,导致二级子菜单也跟着隐藏了,这完全不是我想要的效果。

    三、预期目标

    除了已经实现的两个功能外,还需要:

    • 点击带有三级子菜单的二级菜单项时,能正常展开/收起对应的三级子菜单
    • 同时保持父级的二级子菜单处于展开状态,不会被意外关闭

    四、当前代码示例

    HTML结构

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <nav class="nav-container">
      <ul class="menu main-menu">
        <li class="menu-item menu-level-0">
          <a href="#" class="menu-link">Menu Item 1</a>
        </li>
        <li class="menu-item menu-level-0 menu-has-children">
          <a href="#" class="menu-link">Menu Item 2</a>
          <ul class="sub-menu">
            <li class="menu-item menu-level-1">
              <a href="#" class="menu-link">Submenu Item 1</a>
            </li>
            <li class="menu-item menu-level-1 menu-has-children">
              <a href="#" class="menu-link">Submenu Item 2</a>
              <ul class="sub-sub-menu">
                <li class="menu-item menu-level-2">
                  <a href="#" class="menu-link">Sub Submenu Item 1</a>
                </li>
                <li class="menu-item menu-level-2">
                  <a href="#" class="menu-link">Sub Submenu Item 2</a>
                </li>
                <li class="menu-item menu-level-2">
                  <a href="#" class="menu-link">Sub Submenu Item 3</a>
                </li>
              </ul>
            </li>
            <li class="menu-item menu-level-1">
              <a href="#" class="menu-link">Submenu Item 3</a>
            </li>
            <li class="menu-item menu-level-1">
              <a href="#" class="menu-link">Submenu Item 4</a>
            </li>
          </ul>
        </li>
        <li class="menu-item menu-level-0">
          <a href="#" class="menu-link">Menu Item 3</a>
        </li>
        <li class="menu-item menu-level-0 menu-has-children">
          <a href="#" class="menu-link">Menu Item 4</a>
          <ul class="sub-menu">
            <li class="menu-item menu-level-1">
              <a href="#" class="menu-link">Submenu Item 1</a>
            </li>
            <li class="menu-item menu-level-1 menu-has-children">
              <a href="#" class="menu-link">Submenu Item 2</a>
              <ul class="sub-sub-menu">
                <li class="menu-item menu-level-2">
                  <a href="#" class="menu-link">Sub Submenu Item 1</a>
                </li>
                <li class="menu-item menu-level-2">
                  <a href="#" class="menu-link">Sub Submenu Item 2</a>
                </li>
                <li class="menu-item menu-level-2">
                  <a href="#" class="menu-link">Sub Submenu Item 3</a>
                </li>
              </ul>
            </li>
            <li class="menu-item menu-level-1">
              <a href="#" class="menu-link">Submenu Item 3</a>
            </li>
          </ul>
        </li>
      </ul>
    </nav>
    

    CSS样式

    .nav-container {
      background: #f2f2f2;
      padding: 32px 24px;
    }
    .nav-container .menu, .nav-container .sub-menu, .nav-container .sub-sub-menu {
      list-style-type: none;
      margin: 0;
      padding: 0;
    }
    .nav-container .menu .menu-item, .nav-container .sub-menu .menu-item, .nav-container .sub-sub-menu .menu-item {
      padding: 12px 0;
    }
    .nav-container .menu .menu-item:not(:last-of-type), .nav-container .sub-menu .menu-item:not(:last-of-type), .nav-container .sub-sub-menu .menu-item:not(:last-of-type) {
      border-bottom: 1px solid #9e9e9e;
    }
    .nav-container .menu .menu-item .menu-link, .nav-container .sub-menu .menu-item .menu-link, .nav-container .sub-sub-menu .menu-item .menu-link {
      color: #000;
      font-family: sans-serif;
      text-decoration: none;
    }
    .nav-container .sub-menu, .nav-container .sub-sub-menu {
      display: none;
    }
    .nav-container .sub-menu--active, .nav-container .sub-sub-menu--active {
      display: block;
    }
    .nav-container .sub-menu {
      padding-left: 8px;
    }
    .nav-container .sub-sub-menu {
      padding-left: 16px;
    }
    

    JavaScript代码

    $(function() {
      $('.nav-container').each(function() {
        let nav = new Nav($(this));
      });
    });
    
    let Nav = function Nav(this$obj) {
      this.$obj = this$obj; // .nav-container
      this.primaryNavTriggers();
    };
    
    Nav.prototype.primaryNavTriggers = function primaryNavTriggers() {
      $('.menu-has-children').each(function() {
        $(this).on('click', function() {
          if ($(this).hasClass('menu-level-1')) {
            if ($(this).find('.sub-sub-menu').hasClass('sub-sub-menu--active')) {
              $(this).find('.sub-sub-menu').removeClass('sub-sub-menu--active');
            } else {
              $(this).find('.sub-sub-menu').addClass('sub-sub-menu--active');
            }
          } else if ($(this).hasClass('menu-level-0')) {
            if ($(this).find('.sub-menu').hasClass('sub-menu--active')) {
              $(this).find('.sub-menu').removeClass('sub-menu--active');
            } else {
              $('.sub-menu').each(function() {
                $(this).removeClass('sub-menu--active');
              });
              $(this).find('.sub-menu').addClass('sub-menu--active');
            }
          }
        });
      });
    };
    

    五、问题分析与求助点

    我猜测问题出在事件冒泡上:点击二级菜单项时,事件会向上冒泡到父级的一级菜单项,触发了一级菜单的点击事件,导致它的二级子菜单被关闭。但我试了几种阻止冒泡的方式都没成功,想请教下各位:

    • 怎么正确处理嵌套菜单的点击事件,避免子菜单的点击触发父菜单的事件?
    • 有没有更优雅的方式来实现这种多层级菜单的展开/收起逻辑?

    非常感谢各位的帮助!

    内容来源于stack exchange

    相关产品推荐
    方舟 Agent Plan

    超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

    最近更新时间:2026.04.08 03:13:03