纯原生JavaScript实现点击父div显示对应子项方案及bug修复
问题根源
你现有代码的核心问题是document.querySelector('.child')的查询范围是整个文档,该方法永远只会返回匹配到的第一个class为child的元素,和你当前点击的是哪个父元素没有任何关联,所以无论点击哪个父项,都只会控制第一个p1对应的子项显隐。
纯JS修复实现
核心逻辑是把查询子元素的范围限定在「当前被点击的父元素」内部,不要全局查找子项,就能实现每个父元素独立控制自身子项显隐的效果。
核心改动点
- 废弃全局查询
.child的逻辑,避免跨父元素命中第一个子项 - 事件触发时,通过回调函数内的
this拿到当前触发点击的父元素 - 仅在当前父元素的范围内查找对应的子元素,执行显隐切换
- 建议给
.child类预设默认样式display: none,保证首次点击逻辑正常
完整实现代码
<style> /* 预设子项默认隐藏 */ .child { display: none; padding-left: 20px; } .parent { cursor: pointer; margin: 8px 0; } </style> <!-- 示例DOM结构 --> <div class="parent"> p1 <div class="child">p1对应的子项</div> </div> <div class="parent"> p2 <div class="child">p2对应的子项</div> </div> <div class="parent"> p3 <div class="child">p3对应的子项</div> </div> <div class="parent"> p4 <div class="child">p4对应的子项</div> </div> <script> const parentList = document.getElementsByClassName("parent"); function toggleChild() { // 仅在当前点击的父元素内查找子项 const targetChild = this.querySelector('.child'); // 切换显隐状态 targetChild.style.display = targetChild.style.display === 'block' ? 'none' : 'block'; } // 给所有父项绑定点击事件 for (let i = 0; i < parentList.length; i++) { parentList[i].addEventListener('click', toggleChild, false); } </script>
可选扩展:手风琴效果(单次仅展开一个子项)
如果需要点击当前父项时,自动收起其他所有已展开的子项,只需要把toggleChild方法替换为下面的逻辑即可:
function toggleChild() { const targetChild = this.querySelector('.child'); // 先遍历所有父项,把非当前项的子项全部隐藏 for (let i = 0; i < parentList.length; i++) { const otherChild = parentList[i].querySelector('.child'); if (otherChild !== targetChild) { otherChild.style.display = 'none'; } } // 再切换当前项的显隐状态 targetChild.style.display = targetChild.style.display === 'block' ? 'none' : 'block'; }
内容的提问来源于stack exchange,提问作者user19317490
相关产品推荐
相关产品推荐

