JS待办列表按钮异常:点击编辑项消失、点击删除父容器消失
待办列表按钮功能异常问题解决
问题原因分析
你的代码核心问题是错误使用了原生DOM的remove()方法:
- 原生
Element.remove()方法不需要传入参数,它的作用是让调用该方法的元素自身从DOM中移除。 - 你写的
wrapper.remove(todo)会导致整个#todo-lists容器被移除(错误调用逻辑触发的意外结果),这就是点击delete按钮时容器消失的原因。 - 而
todo.remove(todo_text)会让待办项元素自身被移除,这就是点击edit按钮时对应待办项消失的原因。
另外,当前给每个待办项单独绑定点击事件的方式不够高效,推荐使用事件委托优化。
修正后的代码
基础修复版本(保留原事件绑定方式)
const form = document.getElementById("form"); const wrapper = document.getElementById("todo-lists"); function handleTodo(e) { const btn = e.target.closest("button"); if (!btn) return; const todo = e.currentTarget; if (btn.innerText === "remove") { // 修正:让待办项自身从DOM中移除 todo.remove(); } else if (btn.innerText === "edit") { const todo_text = todo.querySelector("div"); const new_input = document.createElement("input"); new_input.value = todo_text.innerText; todo.prepend(new_input); // 修正:移除原来的文本元素,而非待办项自身 todo_text.remove(); } } function submit(e) { e.preventDefault(); const value = form.elements["todo_input"].value; const todo = document.createElement("div"); todo.addEventListener("click", handleTodo); const todo_text = document.createElement("div"); const del = document.createElement("button"); const edit = document.createElement("button"); del.innerText = "remove"; edit.innerText = "edit"; todo_text.innerText = value; todo.appendChild(todo_text); todo.appendChild(del); todo.appendChild(edit); wrapper.appendChild(todo); e.target.elements["todo_input"].value = ""; } form.addEventListener("submit", submit);
事件委托优化版本(推荐)
将事件监听绑定到父容器#todo-lists上,不需要给每个待办项单独绑定事件:
const form = document.getElementById("form"); const wrapper = document.getElementById("todo-lists"); function handleTodo(e) { const btn = e.target.closest("button"); if (!btn) return; // 通过按钮找到对应的待办项容器 const todo = btn.closest("div"); if (btn.innerText === "remove") { todo.remove(); } else if (btn.innerText === "edit") { const todo_text = todo.querySelector("div"); const new_input = document.createElement("input"); new_input.value = todo_text.innerText; todo.prepend(new_input); todo_text.remove(); } } function submit(e) { e.preventDefault(); const value = form.elements["todo_input"].value; const todo = document.createElement("div"); const todo_text = document.createElement("div"); const del = document.createElement("button"); const edit = document.createElement("button"); del.innerText = "remove"; edit.innerText = "edit"; todo_text.innerText = value; todo.appendChild(todo_text); todo.appendChild(del); todo.appendChild(edit); wrapper.appendChild(todo); e.target.elements["todo_input"].value = ""; } // 事件委托:给父容器绑定点击事件 wrapper.addEventListener("click", handleTodo); form.addEventListener("submit", submit);
HTML部分保持不变:
<div id="container"> <div id="todo-lists"></div> <div id="form-wrapper"> <form id="form"> <input type="text" placeholder="Enter todo" name="todo_input" /> <button>Enter</button> </form> </div> </div>
关键修正点总结
- 删除操作:用
todo.remove()替代wrapper.remove(todo),直接让待办项自身从DOM中移除。 - 编辑操作:用
todo_text.remove()替代todo.remove(todo_text),只移除原文本元素,保留待办项容器。 - 事件委托优化:将事件监听绑定到父容器,利用事件冒泡处理所有子按钮的点击,减少事件监听数量,提升性能。
内容的提问来源于stack exchange,提问作者이준희
相关产品推荐
相关产品推荐

