点击嵌套子菜单时防止父级<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
相关产品推荐
相关产品推荐

