Vanilla JavaScript单次点击触发两次点击事件问题求助
问题描述
我用JS制作高级待办事项列表时遇到如下问题:当列表仅剩1个或2个项时,删除第二个项(或仅剩的项),点击事件会触发两次进而引发错误;但列表项数量多于2个时,删除操作的事件触发完全正常。另外需要说明的是,出现问题的点击事件绑定在按钮内部的SVG元素上。
相关代码片段:
hiqBtn.addEventListener('click',()=>{ let arrPerMinus = []; // 后续会向该数组中添加元素 arrPerMinus.forEach(el => { // 为每个元素绑定点击事件 el.addEventListener('click',e =>{// 注意:el是SVG元素 // 此处为点击后的处理代码 }) }) }
目前功能正常,但因点击事件触发两次导致错误,希望解决该问题让点击事件仅触发一次。
解决方案
1. 清除重复绑定(核心原因)
你每次点击hiqBtn时,都会给arrPerMinus里的SVG元素重复绑定点击事件。比如第一次绑定后,第二次点击hiqBtn又绑定一次,同一个SVG元素就会存在多个点击监听,触发时自然会执行多次。
解决办法:绑定新事件前先移除旧的监听,需要把事件处理函数抽成独立函数:
// 将点击处理逻辑抽成独立函数 function handleSvgClick(e) { // 此处写原有的点击处理代码 } hiqBtn.addEventListener('click',()=>{ let arrPerMinus = []; // 填充元素 arrPerMinus.forEach(el => { // 先移除旧监听,再绑定新监听 el.removeEventListener('click', handleSvgClick); el.addEventListener('click', handleSvgClick); }) }) }
2. 阻止事件冒泡(避免父元素事件触发)
因为SVG是按钮的子元素,点击SVG时事件会向上冒泡到按钮,可能间接引发重复执行。可以在SVG的点击事件中阻止冒泡:
el.addEventListener('click',e =>{ e.stopPropagation(); // 阻止事件向上冒泡到父元素 // 原有的点击处理代码 })
3. 改用事件委托(更优雅的长期方案)
不用给每个SVG单独绑定事件,而是把监听绑定到它们的父容器上,利用事件冒泡统一处理。这样不管列表项如何增删,都无需重复绑定事件,从根源避免重复绑定问题:
// 假设待办列表的父容器类名为todo-list-container document.querySelector('.todo-list-container').addEventListener('click', e => { // 判断点击目标是否为SVG元素或SVG的子元素 if (e.target.tagName === 'SVG' || e.target.closest('svg')) { // 此处写原有的删除处理逻辑 } })
内容的提问来源于stack exchange,提问作者florian dollani
相关产品推荐
相关产品推荐

