JS forEach遍历为同类DOM元素绑定多个事件不生效问题
故障原因
代码不生效的核心问题是箭头函数不绑定自身this。你在事件回调中使用的this不会指向当前触发事件的img元素,而是继承自外层作用域(浏览器环境下非严格模式指向window),因此无法正确修改元素的src属性。
修复方法
两种实现都可以正常运行,按需选择即可:
- 方法1:将事件回调改为普通函数
普通函数作为事件监听回调时,this会默认指向绑定事件的当前DOM元素,可直接修改属性:let gifs = document.querySelectorAll(".changeImg"); gifs.forEach(gif => { gif.addEventListener("mouseover", function() { this.src = "gif.gif"; }); gif.addEventListener("mouseout", function() { this.src = "image.png"; }); }); - 方法2:直接使用遍历拿到的元素引用
forEach遍历时已经拿到了每个img元素的实例(即循环参数gif),不需要依赖this指向,直接操作该变量即可,完全规避this指向混乱的问题:let gifs = document.querySelectorAll(".changeImg"); gifs.forEach(gif => { gif.addEventListener("mouseover", () => { gif.src = "gif.gif"; }); gif.addEventListener("mouseout", () => { gif.src = "image.png"; }); });
可选优化
如果后续页面会动态新增带changeImg类的图片,逐个绑定事件的写法无法覆盖新增元素,且元素数量较多时性能较差,可以改用事件委托实现,只需要在静态父元素上绑定一次事件即可:
// 可将document替换为图片组的最近静态父容器,减少事件冒泡层级 document.addEventListener("mouseover", e => { if (e.target.matches(".changeImg")) { e.target.src = "gif.gif"; } }); document.addEventListener("mouseout", e => { if (e.target.matches(".changeImg")) { e.target.src = "image.png"; } });
内容的提问来源于stack exchange,提问作者Bennpoes
相关产品推荐
相关产品推荐

