removeEventListener失效问题:绑定的点击事件无法单次触发如何解决?
问题分析与解决方案
你的问题根源有两个:
- 循环内定义的命名函数表达式,每次循环都会生成全新的函数实例,导致
removeEventListener找不到对应的函数引用,自然无法移除监听器。 makeAllyTargets每次调用都会往ally_targets数组重复添加元素,多次触发Angels_Grace会让同一个角色被绑定多组监听器,加剧重复触发的问题。
最优解决方案:利用once自动移除监听器
直接使用addEventListener的once配置项,让监听器触发一次后自动销毁,无需手动调用移除方法,代码更简洁可靠:
var ally_targets = [] // 修复:每次生成目标前清空数组,避免重复添加元素 function makeAllyTargets() { ally_targets = [] let maketargets = document.getElementsByClassName('ally_img') for (let i = 0; i < maketargets.length; i++) { ally_targets.push(maketargets[i]) } } var amt_healed function Angels_Grace() { // 单体中等治疗法术 makeAllyTargets() for (let i = 0; i < ally_targets.length; i++) { ally_targets[i].addEventListener('click', function() { const selected_ally = ally_targets.indexOf(this) switch (selected_ally) { case 0: // 骑士 amt_healed = 303 // 确保治疗不超过生命值上限 const currentHp = parseInt(warrior_hp.value) if (currentHp + amt_healed > 550) { Angels_Grace_Part2() warrior_hp.value = 550 } else { Angels_Grace_Part2() warrior_hp.value = currentHp + amt_healed } break // 其他角色的case逻辑保持不变 default: console.log("治疗switch逻辑异常") break } }, { once: true }) // 关键配置:监听器仅触发一次后自动移除 } }
兼容旧环境的方案:手动管理函数引用
如果需要兼容不支持once选项的旧浏览器,可以把处理函数提取到循环内,用闭包保存唯一引用,确保能正确移除:
var ally_targets = [] function makeAllyTargets() { ally_targets = [] let maketargets = document.getElementsByClassName('ally_img') for (let i = 0; i < maketargets.length; i++) { ally_targets.push(maketargets[i]) } } var amt_healed function Angels_Grace() { makeAllyTargets() for (let i = 0; i < ally_targets.length; i++) { // 为每个元素创建独立的处理函数 const handleHealClick = function() { const selected_ally = ally_targets.indexOf(this) switch (selected_ally) { case 0: // 骑士 amt_healed = 303 const currentHp = parseInt(warrior_hp.value) if (currentHp + amt_healed > 550) { Angels_Grace_Part2() warrior_hp.value = 550 } else { Angels_Grace_Part2() warrior_hp.value = currentHp + amt_healed } // 现在可以正确移除,因为handleHealClick是当前元素绑定的唯一函数引用 this.removeEventListener('click', handleHealClick) break // 其他角色的case逻辑保持不变 default: console.log("治疗switch逻辑异常") break } } ally_targets[i].addEventListener('click', handleHealClick) } }
额外注意事项
- 务必修复
makeAllyTargets的数组清空逻辑,否则每次调用Angels_Grace都会重复添加元素,导致同一个角色被绑定多组监听器。 warrior_hp.value默认是字符串类型,需要用parseInt转成数字后再计算,避免出现字符串拼接的错误。
内容的提问来源于stack exchange,提问作者benthedarklord
相关产品推荐
相关产品推荐

