You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

事件递归绑定导致多次执行,如何清除重复绑定的事件监听器?

问题根因

  • 每次执行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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 15:42:03