JavaScript待办列表编辑异常:总是更新首个列表项而非目标项
解决Todo-list编辑时总是修改第一个项的问题
问题根源
你代码里的核心问题是每次点击Edit按钮时,都给add按钮绑定了新的click事件,这些事件会叠加累积。比如你添加3个任务,每个任务的Edit按钮被点击时,都会给add按钮加一次点击事件,当你点击Save时,这3个事件会依次执行,而最早的那个事件对应的是第一个任务的元素,所以最后看起来总是修改第一个项。
修复方案
换个思路:用一个变量记录当前正在编辑的任务元素,然后在表单提交时统一处理「添加新任务」和「保存编辑任务」两种逻辑,避免重复绑定事件。
修改后的完整代码
HTML(无需修改)
<header id="header"> <h1>Todo-list</h1> <form id="form"> <input type="text" id="text" required> <input type="submit" class="add-task" value="add-task"> </form> </header> <section> <div class="tasks"> <h2>Tasks</h2> <!--<div class="task"> <div class="content"> <input type="text" class="task-added" readonly> </div> <div class="actions"> <input type="button" class="edit" value="Edit"> <input type="button" class="delete" value="Delete"> </div> </div> !--> </div> </section>
CSS(无需修改)
* { box-sizing: border-box; } body { width: 100%; height: 100%; margin: 0; padding: 0; background-color: rgba(255, 255, 255, 0.918); } header { display: flex; flex-direction: column; gap: 20px; justify-content: center; align-items: center; } #form { display: flex; gap: 5px; flex-direction: row; justify-content: center; align-items: center; } header h1 { color: orangered; } #form #text { padding: 10px; border-radius: 10px; background-color: orange; color: black; border: none; outline: none; -webkit-border-radius: 10px; -moz-border-radius: 10px; -ms-border-radius: 10px; -o-border-radius: 10px; } #form .add-task { padding: 10px; border: none; outline: none; border-radius: 10px; color: black; background-color: orangered; cursor: pointer; -webkit-border-radius: 10px; -moz-border-radius: 10px; -ms-border-radius: 10px; -o-border-radius: 10px; } .tasks { display: flex; gap: 5px; flex-direction: column; justify-content: center; align-items: center; } .task { padding: 20px; display: flex; background-color: orangered; gap: 10px; border-radius: 5px; flex-direction: row; justify-content: center; align-items: center; -webkit-border-radius: 5px; -moz-border-radius: 5px; -ms-border-radius: 5px; -o-border-radius: 5px; } .task .content .task-added { outline: none; border: none; color: black; padding: 10px; border-radius: 5px; -webkit-border-radius: 5px; -moz-border-radius: 5px; -ms-border-radius: 5px; -o-border-radius: 5px; } .task .content .task-added:not(:read-only) { color: rgb(247, 2, 2); } .task .actions .edit { cursor: pointer; outline: none; background-color: black; border-radius: 5px; padding: 10px; border: none; color: orangered; -webkit-border-radius: 5px; -moz-border-radius: 5px; -ms-border-radius: 5px; -o-border-radius: 5px; } .task .actions { display: flex; flex-direction: row; gap: 10px; } .task .actions .delete { cursor: pointer; background-color: black; outline: none; border-radius: 5px; padding: 10px; border: none; color: orangered; -webkit-border-radius: 5px; -moz-border-radius: 5px; -ms-border-radius: 5px; -o-border-radius: 5px; }
修改后的JavaScript
window.addEventListener('load', () => { const form = document.querySelector("#form"); const input_text = document.querySelector("#text"); const list_ele = document.querySelector(".tasks"); const add = document.querySelector(".add-task"); // 新增变量:记录当前正在编辑的任务输入框 let currentEditingInput = null; form.addEventListener('submit', (e) => { e.preventDefault(); const text = input_text.value.trim(); if (!text) return; if (add.value === "Save" && currentEditingInput) { // 保存编辑:修改当前任务的内容 currentEditingInput.value = text; // 恢复按钮状态 add.value = "add-task"; currentEditingInput = null; } else { // 添加新任务:和原来的逻辑一致 let task = document.createElement("div"); task.classList.add("task"); let task_content = document.createElement("div"); task_content.classList.add("content"); task.appendChild(task_content); let output = document.createElement("input"); output.classList.add("task-added") output.value = text; output.type = "text"; output.setAttribute("readonly", "readonly"); task_content.appendChild(output); let actions = document.createElement("div"); actions.classList.add("actions"); task.appendChild(actions); let edit = document.createElement("button"); edit.classList.add("edit"); edit.innerHTML = "Edit"; actions.appendChild(edit); let DELETE = document.createElement("button"); DELETE.classList.add("delete"); DELETE.innerHTML = "Delete"; actions.appendChild(DELETE); list_ele.appendChild(task); // 给Edit按钮绑定事件:只记录当前要编辑的输入框 edit.addEventListener('click', () => { add.value = "Save"; input_text.focus(); input_text.value = output.value; currentEditingInput = output; }); // 给Delete按钮绑定事件 DELETE.addEventListener('click', () => { task.remove(); // 如果删除的是正在编辑的任务,恢复按钮状态 if (currentEditingInput === output) { add.value = "add-task"; currentEditingInput = null; input_text.value = ""; } }); } input_text.value = ""; }); })
关键修改点
- 新增
currentEditingInput变量,专门记录当前正在编辑的任务输入框,避免通过DOM遍历找目标元素的混乱 - 把「添加任务」和「保存编辑」的逻辑统一放到表单的
submit事件里,不再给add按钮重复绑定事件 - Edit按钮的点击事件只负责切换按钮状态、填充输入框、记录当前编辑的元素,不处理保存逻辑
- 新增Delete按钮的功能,同时处理删除正在编辑任务时的状态恢复
内容的提问来源于stack exchange,提问作者zebi shah
相关产品推荐
相关产品推荐

