点击式响应式Dropdown仅首个生效的JS问题修复求助
修复多个下拉菜单仅第一个生效的问题
你的问题核心在于使用了querySelector()方法——这个方法只会返回匹配选择器的第一个DOM元素,所以第二个下拉菜单的触发按钮和容器完全没有被绑定事件逻辑,自然无法工作。
下面提供两种可行的修复方案:
方案1:遍历所有下拉触发按钮绑定事件
修改JS代码,用querySelectorAll()获取所有触发按钮,逐个绑定点击事件,同时通过DOM关系匹配对应的下拉容器:
let nav = document.querySelector('nav'); let dropdownToggles = nav.querySelectorAll("[data-action='dropdown-toggle']"); let navToggle = nav.querySelector("[data-action='nav-toggle']"); // 遍历所有下拉触发按钮 dropdownToggles.forEach(toggle => { toggle.addEventListener('click', () => { // 从触发按钮向上查找最近的下拉容器 const dropdown = toggle.closest('.dropdown'); // 用toggle简化类名切换逻辑 dropdown.classList.toggle('show'); }); }); navToggle.addEventListener('click', () => { nav.classList.toggle('opened'); });
关键优化点:
querySelectorAll()返回所有匹配的触发按钮集合,确保每个下拉菜单都能被处理closest('.dropdown')通过DOM层级关系绑定触发按钮和对应容器,不依赖元素在页面中的顺序classList.toggle('show')替代原有的if-else判断,简化代码逻辑
方案2:使用事件委托(更高效)
如果后续需要动态添加下拉菜单,事件委托是更优选择——仅在父元素上绑定一次事件,通过事件冒泡处理所有子元素的点击:
let nav = document.querySelector('nav'); let navToggle = nav.querySelector("[data-action='nav-toggle']"); // 事件委托:在nav父元素上监听点击 nav.addEventListener('click', (e) => { // 判断点击目标是否为下拉触发按钮 if (e.target.matches("[data-action='dropdown-toggle']")) { const dropdown = e.target.closest('.dropdown'); dropdown.classList.toggle('show'); } }); navToggle.addEventListener('click', () => { nav.classList.toggle('opened'); });
关键优势:
- 仅绑定一次事件,减少内存占用
- 自动支持后续动态添加的下拉菜单,无需重新绑定事件
内容的提问来源于stack exchange,提问作者kingkylie
相关产品推荐
相关产品推荐

