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

纯JavaScript实现Todo列表:点击DONE按钮仅首个项变绿问题求助

问题原因

你遇到的问题核心是所有列表项都使用了重复的id="item"——HTML规范中id必须是唯一标识,document.getElementById('item')只会返回页面中第一个匹配该id的元素,因此只有第一个列表项能响应变色操作。

解决方案

方案1:修改现有逻辑,传递元素引用

直接调整addItem和change函数,让按钮点击时传递对应的列表项元素,摆脱对重复id的依赖:

const list = [] 
function addItem() { 
  // 声明局部变量,避免全局污染
  const task = document.getElementById('add').value; 
  if (!task) return; // 跳过空任务
  list.push(task); 
  // 移除重复id,改用class标识列表项,同时让按钮点击时传递父元素li
  document.getElementById('unList').innerHTML += "<li class='todo-item'>" + task + "<button onclick='change(this.parentElement)'>done</button></li>";
  // 清空输入框提升体验
  document.getElementById('add').value = '';
} 
function change(item) { 
  item.style.backgroundColor = 'green'; 
}

方案2:事件委托(推荐)

使用事件委托机制,仅给父元素<ul>绑定一次事件监听,通过事件冒泡处理所有按钮点击,更符合现代JavaScript开发规范,且性能更优:

第一步:修改addItem生成的列表项代码

移除按钮的onclick属性,改用class标识按钮:

const list = [];
const unList = document.getElementById('unList');

function addItem() { 
  const task = document.getElementById('add').value; 
  if (!task) return;
  list.push(task); 
  unList.innerHTML += "&lt;li class='todo-item'&gt;" + task + "&lt;button class='done-btn'&gt;done&lt;/button&gt;&lt;/li&gt;";
  document.getElementById('add').value = '';
} 

第二步:添加事件委托监听

// 给ul绑定点击事件,利用事件冒泡处理所有子按钮的点击
unList.addEventListener('click', function(e) {
  // 判断点击的元素是done按钮
  if (e.target.classList.contains('done-btn')) {
    // 找到对应的列表项li
    const todoItem = e.target.closest('.todo-item');
    todoItem.style.backgroundColor = 'green';
  }
});

补充说明

  • 事件委托的优势:无需为每个动态添加的按钮单独绑定事件,后续新增的列表项按钮也能自动生效;减少事件绑定数量,提升页面性能。
  • 始终使用const/let声明变量,避免未声明的变量成为全局变量造成污染。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 21:47:37