使用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
相关产品推荐
相关产品推荐

