deligation.addEventListener is not a function报错原因及JS事件绑定问题咨询
问题原因及解决方案
报错的根本原因
document.querySelectorAll() 返回的是 NodeList 类数组集合,并非单个 DOM 节点,只有单个 DOM 元素才具备 addEventListener 方法,集合本身没有这个方法,所以第一次直接调用 deligation.addEventListener 会抛出is not a function的错误。
循环修改后依然报错的原因
你写的循环逻辑只是做了次数遍历,没有取出集合中对应的单个元素,循环体内依然调用整个 NodeList 集合的 addEventListener 方法,和第一次的错误本质完全一致。
绑定到window能生效的原因
你写的 deligationFunc 本身就是符合事件委托逻辑的代码:会从点击事件的触发源 e.target 逐层向上查找带 data-name 属性的元素,而浏览器事件默认会向上冒泡,绑定到 window 后,页面内所有点击事件最终都会冒泡到 window 触发该函数,逻辑本身没问题所以能正常运行,但这种写法会让页面所有点击都走一遍判断逻辑,性能消耗更高。
正确写法
写法1:循环绑定每个匹配元素
for(let i=0; i<deligation.length; i++){ // 取出当前遍历到的单个DOM节点再绑定事件 deligation[i].addEventListener('click', deligationFunc); }
注意:该写法仅对当前已存在的.contents_box元素生效,如果后续页面动态新增了同类元素,新元素需要重新绑定事件才能触发逻辑。
写法2:事件委托(更推荐)
直接将事件绑定到所有 .contents_box 的最近公共父元素上,不需要循环遍历,后续动态新增的元素也能自动生效,性能更好:
// 替换为你实际的公共父容器选择器,不要直接绑window const commonParent = document.querySelector('.公共父元素的选择器'); commonParent.addEventListener('click', deligationFunc);
内容的提问来源于stack exchange,提问作者Kim
相关产品推荐
相关产品推荐

