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

如何防止createResetHandler函数绑定的点击事件被多次触发

问题原因

每次调用createResetHandler函数时,都会遍历页面上所有.exit元素新增一次点击事件监听,多次调用该函数就会导致同一按钮被绑定多个相同的回调,点击一次就会触发多次执行。

修复方案

以下提供3种常用修复方案,可根据实际场景选择:

方案1:使用once参数(最简便)

绑定事件时添加once: true配置,事件触发一次后会自动解绑,无需额外处理:

function createResetHandler(player) {
  const resetVideo = document.querySelectorAll(".exit");
  resetVideo.forEach(function resetVideoHandler(video) {
    video.addEventListener("click", function resetVideoHandler() {
      player.destroy();
      console.log("createResetHandler");
    // 新增once配置,仅触发一次
    }, { once: true });
  })
}

方案2:绑定前移除旧监听

适合需要多次更新绑定逻辑的场景,先移除之前绑定的同类型事件再新增,避免重复:

// 提取事件处理函数,方便移除操作
function getResetHandler(player) {
  return function() {
    player.destroy();
    console.log("createResetHandler");
  }
}

function createResetHandler(player) {
  const resetVideo = document.querySelectorAll(".exit");
  resetVideo.forEach(function(video) {
    // 移除之前绑定的事件
    video.removeEventListener("click", video._resetHandler);
    // 存储新的处理函数到元素属性上,方便后续移除
    video._resetHandler = getResetHandler(player);
    video.addEventListener("click", video._resetHandler);
  })
}

方案3:加绑定标记避免重复绑定

适合createResetHandler会被多次调用、但绑定逻辑不需要更新的场景,已经绑定过的元素直接跳过:

function createResetHandler(player) {
  const resetVideo = document.querySelectorAll(".exit");
  resetVideo.forEach(function resetVideoHandler(video) {
    // 已绑定过的元素直接跳过
    if (video._hasBindResetEvent) return;
    video._hasBindResetEvent = true;
    video.addEventListener("click", function resetVideoHandler() {
      player.destroy();
      console.log("createResetHandler");
    });
  })
}

内容的提问来源于stack exchange,提问作者user17382064

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 20:45:07