事件递归绑定导致多次执行,如何清除重复绑定的事件监听器?
问题根因
- 每次执行
load()函数都会给按钮新增一个click事件监听器,你在add()里调用了load(),相当于每点击一次就多叠一层监听器,点击触发时所有绑定的监听器都会依次执行,自然会出现1次、2次、4次指数级增长的执行次数 e.stopPropagation()作用是阻止事件向上冒泡到父元素,和重复绑定事件完全无关,且你代码中该方法拼写错误,正确写法为e.stopPropagation(),写错后不会生效- 你绑定监听器使用的是匿名箭头函数,没有保留函数引用,后续无法通过
removeEventListener精准移除对应的监听器
解决方案
方案1:仅绑定一次事件(最推荐)
不要在load()里重复绑定监听器,把绑定逻辑移到初始化阶段只执行一次即可:
const btn = document.getElementById("btn"); var number = 1; function load() { console.log(number); }; function add(e) { number += 1; load(); } // 仅在初始化时绑定一次 btn.addEventListener('click', (e) => add(e)) load();
方案2:每次绑定前移除旧监听器
如果业务逻辑确实需要每次load()都重新绑定监听器,可先保留监听函数的引用,绑定前先移除旧的监听器:
const btn = document.getElementById("btn"); var number = 1; // 存储监听函数的引用 let clickHandler = null; function load() { console.log(number); // 先移除旧监听器再绑定新的 if (clickHandler) { btn.removeEventListener('click', clickHandler); } clickHandler = (e) => add(e); btn.addEventListener('click', clickHandler) }; function add(e) { number += 1; load(); e.stopPropagation(); } load();
临时快速修复方案
也可以改用DOM0级事件绑定写法,新的赋值会自动覆盖之前的绑定,无需手动移除:
function load() { console.log(number); btn.onclick = (e) => add(e) };
内容的提问来源于stack exchange,提问作者misugi
相关产品推荐
相关产品推荐

