在forEach/for循环中绑定addEventListener后点击事件多次触发的原因是什么
问题成因
你的代码存在嵌套循环逻辑错误,是事件被重复绑定的直接原因,具体执行流程如下:
- 外层
for...of循环遍历idReference数组,共执行10次,每轮都会将新获取的DOM元素推入numberElementReference数组 - 每轮外层循环执行时,都会触发一次内层的
for循环,遍历当前numberElementReference中已经存入的所有元素,为每个元素额外绑定一次点击事件
举个实际执行例子:
- 第1轮外层循环:推入
zero元素,内层循环遍历1个元素,给zero绑定第1次点击事件 - 第2轮外层循环:推入
one元素,内层循环遍历2个元素,给zero绑定第2次、one绑定第1次点击事件 - 第3轮外层循环:推入
two元素,内层循环遍历3个元素,给zero绑定第3次、one绑定第2次、two绑定第1次点击事件
……
到10轮外层循环全部执行完后,zero元素累计被绑定了10次点击事件,one被绑定了9次,以此类推,最后一个nine元素被绑定1次,所以点击任意元素都会触发多次事件回调。
修复方案
把内层循环移到外层循环外面即可,只需要在所有DOM元素都收集完成后,统一遍历一次绑定事件:
function initNumberElement(){ let idReference = ['zero','one','two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine']; let numberElementReference = []; let temp = '0'; // 先收集所有DOM元素 for (const key of idReference) { numberElementReference.push(document.getElementById(key)); } // 统一遍历一次绑定事件 for (let i = 0; i < numberElementReference.length; i++) { numberElementReference[i].addEventListener('click', () => { temp = temp + String(i); changeVisualOut(temp) }) } return numberElementReference; }
内容的提问来源于stack exchange,提问作者bale.devit
相关产品推荐
相关产品推荐

