事件委托是将子元素事件监听绑定到共同父元素上,利用事件冒泡和event.target识别目标元素。适用于动态添加元素、提升性能、统一逻辑控制等场景,但focus、blur、mouseenter、mouseleave等不冒泡事件不可委托。

事件委托是什么:用一个监听器管住一堆子元素
事件委托不是新注册一个事件,而是把本该绑定在子元素上的事件监听,改绑到它们的共同父元素上,靠 event.target 来识别真正被点击的是谁。本质是利用了事件冒泡机制——子元素触发事件后,会一层层往上传到父元素。
比如你有一组动态生成的 直接绑定在子节点上,在以下场景会失效或低效: 这是最容易出错的地方:在委托中, 立即学习“Java免费学习笔记(深入)”; 常用安全写法是向上查找匹配的“目标元素”: 不是所有事件都能靠冒泡实现委托。以下事件没有冒泡阶段,绑在父元素上永远收不到: 真正在生产环境用委托时,第一步永远是查 MDN 确认这个事件是否可冒泡——别想当然。,每次新增按钮都去调 addEventListener 很麻烦;换成给它们的容器(比如 click,再判断 event.target 是不是 button,就一劳永逸了。
为什么不用直接绑定?这些情况必须用委托
innerHTML += ''),新节点根本没绑监听器),每个都绑 click 会创建大量监听函数,占用内存且影响性能
event.target 和 event.currentTarget 别搞混event.target 指的是你真正点击的那个最深的元素(比如某个 ),而 event.currentTarget 才是监听器实际绑定的父元素(比如 )。如果你写 event.target.classList.add('active') 却没加类型判断,可能点到文字就给 加 class,而不是整个 。document.getElementById('list').addEventListener('click', function(e) {
const btn = e.target.closest('button'); // 只有点击 button 或其内部元素才命中
if (btn) {
console.log('点了按钮:', btn.dataset.id);
}
});
委托不是万能的:这些事件不支持冒泡,不能委托
focus、blur → 改用 focusin / focusout(它们支持冒泡)mouseenter、mouseleave → 它们本来就是为避免频繁触发设计的,不冒泡;如需委托,改用 mouseover + event.relatedTarget 判断进出load、error(在 等上)→ 这些压根不冒泡,只能单独监听










