如何用event.target.closest实现仅点击图标控制导航栏展开/折叠?
问题原因与解决办法
问题根源
事件绑定在了.hasChild容器上,而子导航链接是它的后代元素。浏览器的事件冒泡机制会让点击子元素的事件向上传递到父容器,触发绑定的切换逻辑,导致导航栏意外折叠/展开。
解决办法
办法1:直接绑定事件到图标元素
既然只需要点击+/-图标触发切换,把事件监听直接加在.collapsible元素上即可,同时阻止事件冒泡避免影响父元素:
const collapsibles = document.getElementsByClassName("collapsible"); Array.from(collapsibles).forEach(el => el.addEventListener('click', event => { event.stopPropagation(); const parentNav = event.target.closest(".hasChild"); parentNav.querySelector(".subnav").classList.toggle('active'); event.target.classList.toggle('collapsible-expanded'); }));
办法2:在事件回调中判断点击目标
如果要保留.hasChild上的事件监听,就在回调里检查点击的是不是图标元素,不符合就跳过切换:
const navHasChilds = document.getElementsByClassName("hasChild"); Array.from(navHasChilds).forEach(el => el.addEventListener('click', event => { // 只允许点击.collapsible元素时执行切换 if (!event.target.closest(".collapsible")) return; const parentNav = event.target.closest(".hasChild"); parentNav.querySelector(".subnav").classList.toggle('active'); event.target.closest(".collapsible").classList.toggle('collapsible-expanded'); }));
额外优化:精简CSS代码
当前.collapsible和.collapsible-expanded样式大量重复,可以合并基础样式,只修改差异部分:
.collapsible { color: white; cursor: pointer; padding: 0px; width: 100%; border: none; text-align: left; outline: none; font-size: 17px; } .collapsible:after { content: '\002B'; color: white; font-weight: bold; float: right; margin-right: 8px; } /* 仅修改展开状态的图标内容 */ .collapsible.collapsible-expanded:after { content: '\2212'; }
内容的提问来源于stack exchange,提问作者Divya Bharathi
相关产品推荐
相关产品推荐

