jQuery实现折叠菜单:点击目标子菜单时关闭其余子菜单
侧边栏折叠菜单:点击展开当前子菜单并关闭其他子菜单
场景与需求
侧边栏菜单HTML结构如下,子菜单为可折叠类型:
<ul class="block-navigation" id="sidebar-navigation"> <li class="navigation-item has-child navigation-submenu"> <a class="open-submenu" href="#"> School Affairs <em></em> </a> <ul class="block-navigation-submenu"> <li class="navigation-item"> <a class="" href="#"> <span>School Affairs</span> </a> </li> <li class="navigation-item"> <a class="" href="#"> <span>National Schools</span> </a> </li> <li class="navigation-item"> <a class="" href="#"> <span>Teacher Transfers</span> </a> </li> </ul> </li> <!-- 其他类似的带子菜单的li项 --> <li> ----- ----- </li> </ul>
需求:点击父级<a>元素内的<em>元素触发子菜单时,展开当前子菜单,同时关闭除目标子菜单外的所有其他子菜单。
尝试的代码及问题
以下是尝试的jQuery代码,但仅能实现子菜单展开,无法关闭其他子菜单:
$("#sidebar-navigation li.navigation-submenu > a > em").on('click', function(e) { e.preventDefault(); let $el = $(this).parent().parent('li'); $($el).not($el).removeClass("active"); $($el).not($el).find(".navigation-submenu").slideUp(); $(this).parent().parent('li').toggleClass("active"); $(this).parent().parent('li').find(".navigation-submenu").slideToggle(); });
问题原因
代码中$($el).not($el)的逻辑错误:$el本身就是当前点击对应的<li>元素,用.not($el)过滤后会得到空集合,因此不会对其他子菜单执行任何关闭操作。
修正后的代码
调整逻辑,先选中所有带子菜单的<li>,排除当前点击的项后,再执行关闭操作:
$("#sidebar-navigation li.navigation-submenu > a > em").on('click', function(e) { e.preventDefault(); // 获取当前点击对应的父级li元素 const $currentLi = $(this).closest('li.navigation-submenu'); // 选中所有其他带子菜单的li,移除active类并收起子菜单 $('#sidebar-navigation li.navigation-submenu').not($currentLi) .removeClass('active') .find('.block-navigation-submenu').slideUp(); // 切换当前li的active状态,展开/收起当前子菜单 $currentLi.toggleClass('active') .find('.block-navigation-submenu').slideToggle(); });
代码说明
- 使用
.closest('li.navigation-submenu')更简洁健壮地获取当前点击元素的父级带子菜单的<li>,替代多次.parent()的写法。 - 先选中所有
li.navigation-submenu,用.not($currentLi)排除当前项,对剩下的元素执行移除active类和收起子菜单的操作。 - 最后单独处理当前项的状态切换和子菜单的展开/收起。
内容的提问来源于stack exchange,提问作者user3733831
相关产品推荐
相关产品推荐

