多级下拉菜单点击异常:点击子菜单收起而非展开问题
我来帮你搞定这个多级下拉菜单的问题!你现在遇到的核心问题是:点击子菜单链接时,菜单会直接收起而不是展开下级选项,这是因为你的JS代码在处理点击事件时,错误地操作了所有层级的子菜单,还没考虑到事件冒泡的影响。
问题根源分析
你的原代码有两个关键问题:
- 选择器
$('.main-menu ul li a')匹配了所有层级的<a>标签,包括子菜单里的链接,点击子菜单时会触发和主菜单一样的逻辑; - 事件里的
$('.sub-menu').slideUp()会把页面上所有子菜单都收起来,包括你正要展开的下级菜单; - 没有阻止事件冒泡,子菜单的点击会向上传递到父级的
<a>,导致父菜单的状态被意外修改。
修复后的代码
JavaScript部分
$(document).ready(function() { $('.main-menu ul li a').click(function(e) { // 仅当当前链接后存在子菜单时执行下拉逻辑 if ($(this).next().hasClass('sub-menu')) { e.preventDefault(); e.stopPropagation(); // 阻止事件冒泡,避免触发父级菜单的点击事件 const $currentSubMenu = $(this).next('.sub-menu'); const $parentMenuItem = $(this).closest('li'); // 收起当前菜单同级的其他子菜单,并移除它们的active类 $parentMenuItem.siblings().find('.sub-menu').slideUp(); $parentMenuItem.siblings().find('a').removeClass('active'); // 切换当前子菜单的显示状态,更新active类 if ($currentSubMenu.is(':visible')) { $(this).removeClass('active'); $currentSubMenu.slideUp(); } else { $(this).addClass('active'); $currentSubMenu.slideDown(); } } }); });
HTML部分(无需修改)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="main-menu"> <ul id="menu-main-menu" class="menu"> <li class="menu-item"> <a href="http://localhost/barcoun/"><span>Home</span></a> </li> <li class="menu-item"> <a href="http://localhost/barcoun/about-us/"><span>About Us</span></a> </li> <li class="menu-item"> <a href="http://localhost/barcoun/contact-us/"><span>Contact Us</span></a> </li> <li class="menu-item"> <a href="#" class="menu-image-title-after"><span>Enrolments</span></a> <ul class="sub-menu" style="display: none"> <li class="menu-item"> <a href="#"><span>Enrolment</span></a> <ul class="sub-menu" style="display: none"> <li class="menu-item"> <a href="http://localhost/barcoun/enrollment-details-by-bar-association/"><span>Enrolment Details</span></a> </li> </ul> </li> </ul> </li> </ul> </div>
关键改进点
- 阻止事件冒泡:用
e.stopPropagation()避免子菜单的点击触发父级菜单的事件,防止父菜单意外收起; - 精准控制收起范围:只收起当前菜单同级节点的子菜单,而不是全局所有子菜单,确保下级菜单能正常展开;
- 清晰的状态切换:用
slideDown替代slideToggle,让展开/收起的逻辑更明确,减少状态混乱的可能; - 作用域锁定:通过
closest('li')限定操作范围,确保所有修改只影响当前菜单及其同级选项。
内容的提问来源于stack exchange,提问作者tester
相关产品推荐
相关产品推荐

