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

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>

关键修正点总结

  1. 删除操作:用todo.remove()替代wrapper.remove(todo),直接让待办项自身从DOM中移除。
  2. 编辑操作:用todo_text.remove()替代todo.remove(todo_text),只移除原文本元素,保留待办项容器。
  3. 事件委托优化:将事件监听绑定到父容器,利用事件冒泡处理所有子按钮的点击,减少事件监听数量,提升性能。

内容的提问来源于stack exchange,提问作者이준희

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 21:52:41