0Pricing
JavaScript Academy · 课时

使用委托处理动态列表

管理运行时添加的元素的事件。

使用委托处理动态列表 是 CoddyKit 上的免费 JavaScript Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 JavaScript Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 JavaScript Academy 课程共包含 4 节课。

动态元素问题

当您直接为元素附加监听器时,在设置之后添加到 DOM 的任何元素都没有监听器。事件委托解决了这个问题,因为父元素上的监听器也能捕获未来子元素触发的事件。

直接监听器会失效

这里为现有项目添加了监听器。新追加的项目没有任何监听器,因此不会响应操作。

document.querySelectorAll(".item").forEach((el) =>
  el.addEventListener("click", handle)
);
list.appendChild(newItem); // newItem has NO handler

委托会自动生效

如果父元素上有委托监听器,新项目会自动得到处理。每次插入后都不需要重新绑定。

list.addEventListener("click", (e) => {
  const item = e.target.closest(".item");
  if (item) console.log("Clicked", item.dataset.id);
});
list.appendChild(newItem); // works immediately

添加项目

构建新元素并将其追加。由于父元素已经进行委托,它们一出现就可以交互。

function addItem(text) {
  const li = document.createElement("li");
  li.className = "item";
  li.textContent = text;
  list.appendChild(li);
}

移除项目

删除操作也很简洁。委托处理函数可以检测行内的删除按钮,然后移除该行。

list.addEventListener("click", (e) => {
  if (e.target.matches(".delete-btn")) {
    e.target.closest(".item").remove();
  }
});

区分子操作

一行中可能有多个可交互部分。使用 matches() 或 closest() 判断用户点击了哪一部分,然后进行分支处理。

list.addEventListener("click", (e) => {
  if (e.target.matches(".edit-btn")) edit(e);
  else if (e.target.matches(".delete-btn")) del(e);
});

根据数据进行渲染

一种常见模式是:将状态保存在数组中,根据数组渲染各行,并委托处理点击。重新渲染会替换子元素,但唯一的父元素监听器始终不受影响。

function render(items) {
  list.innerHTML = items
    .map((i) => "<li class=\"item\" data-id=\"" + i.id + "\">" + i.name + "</li>")
    .join("");
}

不再为清理工作烦恼

使用逐元素监听器时,必须记得在删除节点前调用 removeEventListener,以避免内存泄漏。事件委托消除了这一负担:删除子元素不会使任何监听器成为孤立对象。

切换类名

事件委托非常适合与类名切换结合,用于表示选中状态。处理函数找到对应的行并切换一个类名。

list.addEventListener("click", (e) => {
  const row = e.target.closest(".item");
  if (row) row.classList.toggle("selected");
});

读取稳定标识

由于重新渲染时 DOM 节点会被替换,因此不要保存对这些节点的引用。应在 data-id 中保存稳定标识符,并在处理函数中根据该标识符查找数据模型。

const id = e.target.closest(".item").dataset.id;
const record = state.find((r) => r.id === id);

输入事件也可以委托

事件委托并不局限于点击。对于动态添加的表单字段,也可以用相同方式委托 input 或 change 事件。

form.addEventListener("input", (e) => {
  if (e.target.matches(".qty")) recalc(e.target);
});

快速检查

动态列表与事件委托。

回顾

事件委托在动态列表中尤其有效:一个父元素监听器即可处理当前和未来的子元素,重新渲染后仍然有效,也不需要逐节点清理。使用 matches() 和 closest() 根据子操作进行分支处理,并将稳定标识符存储在 data-* 中,以便处理函数找到数据模型。

常见问题解答

「使用委托处理动态列表」课时是免费的吗?

是的 — 「使用委托处理动态列表」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 JavaScript Academy 课程的其余内容,请升级到 CoddyKit PRO。 JavaScript Academy 课程共包含 4 节课。

「使用委托处理动态列表」这节课中我会学到什么?

管理运行时添加的元素的事件。 你通过在浏览器中直接运行的动手代码来练习 JavaScript Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 JavaScript Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 JavaScript Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。

「使用委托处理动态列表」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 JavaScript Academy 课中编写并运行代码吗?

能。每节 JavaScript Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 捕获阶段与冒泡阶段
  2. 事件委托模式
  3. 使用委托处理动态列表
  4. 自定义事件
← 返回 JavaScript Academy