如何防止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
相关产品推荐
相关产品推荐

