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

Odin Project待办列表项目任务添加重复问题求助

问题分析与解决方案

Hey there! 作为新手能做到模块化开发已经很棒了,别着急,你的问题其实很常见——事件重复绑定导致的重复执行。

问题根源

每次点击「添加项目」按钮时,你都在做两件重复的事:

  1. 用 document.querySelectorAll(".overview") 获取所有已存在的项目元素,然后给每一个都重新绑定一次click事件。比如创建第4个项目时,前3个项目已经各被绑定了3次click事件,加上这次就是4次;
  2. 把taskBtn的click事件绑定也放在了projectBtn的点击回调里,这意味着每创建一个项目,就给任务按钮多绑一层事件监听。最后4个项目的话,点击任务按钮会触发4次回调,自然生成4个重复任务。

解决方案

我们需要把事件监听只绑定一次,而不是每次创建项目都重复绑定。这里推荐用「事件委托」来处理动态生成元素的事件,比逐个绑定更高效。

1. 用事件委托处理项目点击事件

找一个包含所有.overview元素的父容器(比如假设你的项目都放在#projects-container这个div里),给父容器绑定一次点击事件,不管后来新增多少项目,都能触发:

// 把这段代码放在全局作用域,只执行一次,不要放在projectBtn的点击回调里
document.querySelector('#projects-container').addEventListener('click', function(e) {
  // 找到点击的.overview元素(考虑点击到项目内部子元素的情况)
  const targetProject = e.target.closest('.overview');
  if (!targetProject) return; // 如果点击的不是项目元素,直接退出

  const dataId = targetProject.getAttribute('data-id');
  const result = findProject(dataId);
  changeProject(result.title);
  document.querySelector('.hide').style.display = "block";
});

2. 把任务按钮的事件移到全局

把taskBtn的点击事件绑定也放在全局,只执行一次:

// 同样放在全局,不要嵌套在projectBtn的回调里
taskBtn.addEventListener("click", function(event) {
  event.preventDefault(); // 记得显式传event参数,避免依赖全局event

  let name = document.getElementById("task").value;
  let priority = document.getElementById("priority").value;
  let date = document.getElementById("date").value;
  let taskId = crypto.randomUUID();
  let info = document.getElementById("info").value;
  let task = new ListItems(name, priority, date, info, taskId);
  
  makeTask(name, date, taskId);
  // 这里补充:需要把任务添加到当前选中的项目里
  // 建议你声明一个全局变量比如currentProjectId,在点击项目时赋值,然后这里找到对应的Project实例调用addListItem
  // const currentProject = findProject(currentProjectId);
  // currentProject.addListItem(task);
});

3. 移除原代码中的重复绑定

把你原来写在projectBtn回调里的这两段代码删掉:

overview.forEach(item=> item.addEventListener( "click",function() { ... }))
taskBtn.addEventListener( "click",function () { ... })

额外小提示

  • 始终在事件回调里显式传入event参数,不要依赖浏览器的全局event对象,避免兼容性问题;
  • 记得维护一个「当前选中项目」的状态(比如全局变量currentProjectId),这样添加任务时才能准确关联到对应的项目;
  • 可以给.overview元素加一个「选中」样式,让用户直观看到当前操作的是哪个项目。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 06:38:40