JavaScript移动端菜单仅首个元素生效、需双击触发问题咨询
问题根源
- 仅首个元素生效:
document.querySelector()的设计逻辑就是只返回匹配选择器的第一个DOM节点,无法获取所有同类菜单项。同时你全局提前选中的子菜单永远是第一个匹配的节点,即便给多个按钮绑定事件,触发时操作的也不是当前点击项对应的子菜单。 - 需要双击触发:
element.styleAPI仅能读取标签内style属性写的内联样式,初始状态下你的子菜单没有设置内联display: none,第一次点击时读取到的style.display是空值,不满足=== 'none'的判断,会走到else分支把子菜单设为隐藏,相当于第一次点击只完成了初始隐藏操作,第二次点击才会触发显示逻辑,才会出现需要双击的现象。 - 额外结构错误:你提供的HTML中第二个带
menu-item-has-children类的<li>标签提前闭合,内部<a>标签也存在多余闭合标签,对应子菜单<ul>被写到了<li>节点外部,DOM层级关系错误,JS无法正确关联菜单项和对应的子菜单。
修复方案
- 先修正HTML结构错误,删除第二个菜单项的多余
</li>和</a>标签,确保子菜单完全包裹在对应父<li>标签内部,链接文本放在<a>标签内部。 - 初始子菜单隐藏建议用CSS实现,不要依赖内联样式:
.navigation-main-mobile .sub-menu { display: none; }
- 替换原有JS逻辑,遍历所有带二级菜单的父项绑定事件,事件触发时操作当前点击项内部的子菜单:
// 获取所有带子菜单的菜单项 const parentMenuItems = document.querySelectorAll('.navigation-main-mobile .menu-item-has-children'); parentMenuItems.forEach(item => { item.addEventListener('click', function(e) { // 阻止a标签默认的锚点跳转行为 e.preventDefault(); // 查找当前点击菜单项下的子菜单 const currentSubMenu = this.querySelector('.sub-menu'); // 切换显隐状态 currentSubMenu.style.display = currentSubMenu.style.display === 'none' ? 'block' : 'none'; // 更简洁的写法可以用class切换,先定义.hidden类 { display: none; },直接写下面这行即可 // currentSubMenu.classList.toggle('hidden'); }) })
内容的提问来源于stack exchange,提问作者William
相关产品推荐
相关产品推荐

