事件委托是指将一个 listener 附加到共同的祖先元素,而不是为每个子元素分别附加 listener,并使用事件冒泡机制来识别实际被交互的子元素(通过 event.target)。
js
// ❌ without delegation: one listener PER item (and broken for new items)
document.().(
li.(, handle));
.().(, {
li = e..();
(li) (li..);
});
工作原理
当你点击 <li> 时,事件会冒泡上升:li → ul → body → document。<ul> 上的 listener 因此会接收来自其任何 <li> 子元素的点击事件,而 e.target 会告诉你具体是哪个元素被点击了。closest("li") 从目标元素向上遍历以找到预期的元素(也处理对内部元素的点击)。
为什么这很重要
- 性能/内存:一个 listener 代替数百或数千个。
- 自动适用于动态添加的元素 — 稍后添加的新
<li>不需要新 listener,因为父元素已经在处理。 - 更简单的清理:移除一个 listener,而不是很多。
注意事项
它依赖于冒泡,所以对于不冒泡的事件不适用(focus、blur — 改用 focusin/focusout)。这正是 React 内部使用的技术(整个应用的单个根 listener)。
