jQuery多级菜单问题求助:实现选中子菜单的显示与隐藏
解决jQuery多级菜单仅展开当前子菜单的问题
我明白你遇到的困扰了——原代码里因为子菜单选择逻辑的问题,导致mobileMenuItem.css()偶尔返回undefined,使得菜单行为不稳定。咱们来一步步修复它,实现点击仅展开/关闭当前子菜单,其余菜单保持原有状态的效果。
问题分析
原代码中,当点击的是子菜单里的链接(比如L2)时,$(e.target).parent().find('> ul.sub-menu')其实是在找当前li的直接子菜单,但如果当前li没有子菜单(或者你点的是更深层的元素),就会得到一个空的jQuery对象,这时候调用.css('display')自然返回undefined,导致逻辑出错。
修复后的完整代码
首先需要给子菜单添加默认隐藏的CSS样式:
ul.sub-menu { display: none; }
然后是优化后的jQuery代码:
$(document).ready(function() { // 给所有hdrMenu下的li绑定点击事件 $('ul.hdrMenu li').on('click', function(e) { // 直接获取当前li的直接子菜单(最准确的方式) const $subMenu = $(this).children('ul.sub-menu'); // 如果当前li没有子菜单,直接退出,不做任何操作 if (!$subMenu.length) { return; } // 切换当前子菜单的显示/隐藏状态 $subMenu.slideToggle(); // 阻止默认跳转(因为点击的是a标签) e.preventDefault(); // 阻止事件冒泡,避免父级li的点击事件被触发 e.stopPropagation(); }); });
HTML部分可以保留你原来的结构:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <ul class="hdrMenu"> <li><a href="#">Inicio</a></li> <li><a href="#">Servicios</a> <ul class="sub-menu"> <li><a href="#">L1</a></li> <li><a href="#">L2</a> <ul class="sub-menu"> <li><a href="#">L2-1</a></li> <li><a href="#">L2-2</a></li> </ul> </li> <li><a href="#">L3</a></li> <li><a href="#">L4</a> <ul class="sub-menu"> <li><a href="#">L4-1</a></li> <li><a href="#">L4-4</a></li> </ul> </li> </ul> </li> <li><a href="#">Acerca de</a> <ul class="sub-menu"> <li><a href="#">Sub1</a></li> <li><a href="#">Sub2</a></li> <li><a href="#">Sub3</a></li> <li><a href="#">Sub4</a></li> </ul> </li> <li><a href="#">Contacto</a></li> </ul>
关键优化点
- 准确选择子菜单:用
$(this).children('ul.sub-menu')直接获取当前li的直接子菜单,避免了原代码中复杂且容易出错的父元素查找逻辑。 - 空对象检查:通过
$subMenu.length判断子菜单是否存在,避免对空对象执行操作导致的undefined问题。 - 简化逻辑:用
.slideToggle()替代手动判断display状态,自动切换显示/隐藏,代码更简洁可靠。 - 事件控制:
e.preventDefault()阻止a标签的默认跳转,e.stopPropagation()阻止事件冒泡到父级菜单,确保只有当前点击的菜单触发状态变化。
这样修改后,点击任意菜单只会展开/关闭它自己的子菜单,其他菜单保持原来的状态,而且不会再出现undefined的问题啦!
内容的提问来源于stack exchange,提问作者Marco Jacobo
相关产品推荐
相关产品推荐

