如何在循环中移除子元素EventListener?解决内部元素触发父元素事件问题
解决内部元素触发父容器点击事件的问题
问题场景
给包含输入框、段落等内部元素的div绑定了click事件,但点击这些内部元素时,父div的click事件也会被触发。希望仅点击div本身时才执行事件逻辑,尝试使用event.target和removeEventListener未成功。
解决方案
问题根源是事件冒泡:内部元素的点击事件会向上传递到父容器,触发绑定的处理函数。你之前尝试的removeEventListener无效,是因为从未给内部元素绑定过该事件处理函数。
正确的做法是在父div的点击事件处理函数中,判断点击的目标是否为div本身:
- 获取事件对象
event - 对比
event.target(实际被点击的元素)和this(绑定事件的div) - 如果两者不相等,直接终止函数执行,不处理后续逻辑
修改后的代码
HTML代码
<!DOCTYPE html> <html lang="en"> <head> <style> .frame { width: 200px; height: 200px; background-color: brown; } input { margin: auto; } p { text-align: center; } </style> </head> <body> <div class="frame"> <input placeholder="same effect here"> <p>CLICK DIV</p> </div> <div class="frame"> <input placeholder="same effect here"> <p>CLICK DIV</p> </div> <div class="frame"> <input placeholder="same effect here"> <p>CLICK DIV</p> </div> </body> </html>
JavaScript代码
const labels = document.querySelectorAll(".frame"); for (var i = 0; i < labels.length; ++i) { labels[i].addEventListener("click", function touch(event) { // 判断点击的是否是div本身,不是则直接返回 if (event.target !== this) { return; } if (this.clientWidth == 200) { this.style.width = "400px"; this.style.height = "400px"; } else { this.style.width = "200px"; this.style.height = "200px"; } }); }
补充说明
如果需要更灵活的判断(比如允许点击div内的某些特定子元素时触发事件),可以通过event.target的类名、标签名等进行筛选,示例如下:
// 仅当点击的是div本身或者p标签时触发逻辑 if (event.target !== this && event.target.tagName !== 'P') { return; }
内容的提问来源于stack exchange,提问作者Table
相关产品推荐
相关产品推荐

