导航菜单展开/折叠状态管理的jQuery代码转纯JS遇阻求助
导航菜单展开/折叠逻辑的纯JS转换方案
原jQuery代码的核心逻辑是:点击下拉按钮时,移除所有激活状态(带toggle-on类)的下拉按钮的激活状态,但保留当前点击按钮和当前按钮所在子菜单的父级下拉按钮的状态。以下是对应的纯JS实现:
完整纯JS代码实现
const container = document.querySelector('.main-navigation'); container.querySelectorAll('.dropdown-toggle').forEach(item => { item.addEventListener('click', function(e) { const _this = this; // 用this替代e.target,避免按钮内部元素触发时指向错误 e.preventDefault(); // 1. 获取所有处于激活状态的下拉按钮 const activeToggles = container.querySelectorAll('.dropdown-toggle.toggle-on'); // 2. 构建需要排除的元素列表(当前按钮 + 父级下拉按钮) // 先找到当前按钮所在菜单项的所有父级子菜单 const parentSubmenus = _this.closest('.menu-item').querySelectorAll('.sub-menu, .children'); // 提取这些父级子菜单对应的前置下拉按钮 const parentToggles = Array.from(parentSubmenus) .map(submenu => submenu.previousElementSibling) .filter(el => el?.classList.contains('dropdown-toggle')); // 组合成最终排除列表 const excludeList = [_this, ...parentToggles]; // 3. 遍历处理非排除项的激活按钮 activeToggles.forEach(toggle => { if (!excludeList.includes(toggle)) { toggle.classList.remove('toggle-on'); toggle.setAttribute('aria-expanded', 'false'); } }); // 可选:切换当前按钮的激活状态 _this.classList.toggle('toggle-on'); _this.setAttribute('aria-expanded', _this.classList.contains('toggle-on')); }); });
关键逻辑拆解
1. 替代jQuery的.not()方法
jQuery的.not()是从选中集合中排除指定元素,纯JS中可以通过以下方式实现:
- 先获取所有目标元素集合
- 构建需要排除的元素数组
- 遍历集合时用
!excludeList.includes(toggle)判断是否需要处理
2. 替代jQuery的.parents()和.prev()
- jQuery的
_this.parents('.children, .sub-menu')→ 纯JS用_this.closest('.menu-item').querySelectorAll('.sub-menu, .children'),先定位当前按钮所在的菜单项,再获取所有父级子菜单 - jQuery的
.prev('.dropdown-toggle')→ 纯JS用submenu.previousElementSibling,获取子菜单的前一个同级元素,再筛选出下拉按钮
3. 避免事件目标错误
用this代替e.target,因为按钮内部包含svg和span标签,e.target可能指向这些子元素,而this始终指向绑定事件的按钮本身,更可靠。
内容的提问来源于stack exchange,提问作者leemon
相关产品推荐
相关产品推荐

