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

使用HTML5拖拽API交换待办项后删除按钮事件监听器丢失求助

问题根因

  • 你在handleDrop方法中直接修改了两个待办项<li>元素的innerHTML属性:
    • 删除按钮的点击事件是绑定在<li>内部的.delete-todo-item子元素上的,替换innerHTML会销毁原有子元素、生成全新的子节点,原有的事件绑定自然就失效了。
    • 标记置灰的事件是直接绑定在<li>元素本身上的,替换innerHTML不会销毁<li>元素本身,所以对应事件可以正常触发。

推荐解决方案:使用事件委托优化事件绑定

不用给每个删除按钮单独绑定事件,直接将删除事件绑定在待办列表的父容器(比如所有<li>的上级<ul>元素)上,后续不管DOM怎么更新,事件都不会失效:

// 将#todo-list替换为你实际使用的待办列表父容器选择器
document.querySelector('#todo-list').addEventListener('click', function(e) {
  // 判断点击目标是否为删除按钮
  if (e.target.classList.contains('delete-todo-item')) {
    e.stopPropagation();
    const toDo = e.target.parentElement;
    const itemID = toDo.getAttribute("data-id")
    todos = todos.filter(function (item) {
        return item.timeCreated != itemID;
    })
    addToLocalStorage(todos);
    toDo.remove()
    emptyTodoList()
  }
})

使用该方案后,你原来给单个删除按钮绑定事件的代码可以直接删除,不会再出现拖拽后事件失效的问题。

备选解决方案:拖拽完成后重新绑定事件

如果你不想修改现有事件绑定逻辑,也可以在handleDrop方法替换innerHTML之后,重新给两个<li>的删除按钮绑定事件:

function handleDrop(e) {
    e.stopPropagation();
    e.preventDefault();
    const tempId = dragSrcEl.getAttribute("data-id");
    const tempClassList = dragSrcEl.classList.value
    dragSrcEl.className = this.classList.value;
    dragSrcEl.setAttribute("data-id", this.getAttribute("data-id"))
    this.className = tempClassList;
    this.setAttribute("data-id", tempId)
    if (dragSrcEl !== this) {
        dragSrcEl.innerHTML = this.innerHTML;
        this.innerHTML = e.dataTransfer.getData('text/html');
        // 新增代码:重新为两个li的删除按钮绑定事件
        dragSrcEl.querySelector(".delete-todo-item").addEventListener("click", deletetodoEventListener)
        this.querySelector(".delete-todo-item").addEventListener("click", deletetodoEventListener)
    }
    return false;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 10:57:01