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

JavaScript中待办列表EventListener触发时重复累加执行的问题求助

解决待办事项删除按钮重复触发事件的问题

问题根源

你每次点击ADD按钮时,都会重新获取所有.close-btn元素,然后给每个按钮再绑定一次点击事件。比如第一次添加任务后,1个按钮绑定1次事件;第二次添加任务后,2个按钮各绑定1次,第一个按钮就有2个监听器,点击一次会触发2次,次数自然累加。

最简单的解决方法:给新按钮直接绑定事件

不用遍历所有按钮,在创建新的关闭按钮后,直接给它单独绑定事件,每个按钮只会被绑定一次:

const addBtn = document.getElementById("add-btn")
const divWrp = document.getElementById("wrapper")
let a = 1;
let b = 0;

addBtn.addEventListener("click", function(){
    let newTask = document.createElement("div")
    newTask.classList.add("task")
    newTask.textContent = "Task" + a
    let closeBtn = document.createElement("button")
    closeBtn.classList.add("close-btn")
    
    // 直接给新创建的关闭按钮添加事件
    closeBtn.addEventListener("click", function(){
        b += 1
        console.log("hello world" + b)
        // 这里可以添加删除任务的逻辑:
        // newTask.remove()
    })
    
    newTask.append(closeBtn)
    divWrp.append(newTask)
    a += 1;
})

更优雅的方案:事件委托

利用事件冒泡原理,把事件绑定在父容器#wrapper上,不管之后添加多少新任务,都能正常触发,不用给每个按钮单独绑定:

const addBtn = document.getElementById("add-btn")
const divWrp = document.getElementById("wrapper")
let a = 1;
let b = 0;

addBtn.addEventListener("click", function(){
    let newTask = document.createElement("div")
    newTask.classList.add("task")
    newTask.textContent = "Task" + a
    let closeBtn = document.createElement("button")
    closeBtn.classList.add("close-btn")
    
    newTask.append(closeBtn)
    divWrp.append(newTask)
    a += 1;
})

// 父容器监听点击,判断点击目标是不是关闭按钮
divWrp.addEventListener("click", function(e){
    if(e.target.classList.contains("close-btn")){
        b += 1
        console.log("hello world" + b)
        // 删除对应的任务项
        e.target.parentElement.remove()
    }
})

为啥之前把循环放外部没用?

页面刚加载时,.close-btn还不存在,循环绑定事件也绑不到任何元素;后来新增的按钮,外部的循环不会自动重新执行,所以事件绑定不上,自然无效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 10:40:30