事件委托是利用事件冒泡机制,在父元素上统一监听子元素事件,通过event.target和closest()精准识别目标节点,实现一次绑定、动态生效、高效维护。

直接在父元素上监听点击事件,利用事件冒泡 + event.target 判断真实点击目标,就能统一管理所有当前和未来新增的子元素——不用给每个子元素单独绑事件,也不用为动态插入的元素重复绑定。
选对父容器,别跨层级委托
委托应尽量靠近子元素,比如列表用 点击发生后, 只要父元素存在且事件监听器已绑定,后续用 JS 插入的新子元素(例如 事件委托不是万能的,有些情况需额外判断:,表格用 或
。离得太远(如直接绑到
document)虽能工作,但冒泡路径变长、响应延迟增加,还容易被中间层的 stopPropagation() 拦截。
ul 管理所有 li)body 或 document 处理按钮点击(除非全局行为)用 event.target 精准识别触发元素
event.target 指向**最底层被点击的 DOM 节点**(可能是子元素,也可能是子元素里的 span 或 img)。所以不能只看标签名,要向上查找匹配的“业务目标”。
event.target.closest('selector') 安全获取目标子元素(自动向上找最近匹配项)if (e.target.tagName === 'LI') —— 如果用户点的是 li 里的文字或图标,e.target 就是那个 textNode 或 span,条件会失败代码写法要兼顾静态与动态场景
ul.appendChild(newLi))无需额外操作,点击即生效。
closest() 获取业务单元,再读取其数据属性(如 data-id)或结构信息
const list = document.getElementById('item-list');
list.addEventListener('click', e => {
const item = e.target.closest('li');
if (!item) return;
console.log('操作第', item.dataset.id);
});
注意边界与兼容性细节
e.stopPropagation(),否则冒泡中断,父元素收不到input、select)的某些事件(如 input、change)也支持冒泡,可委托;但 focus/blur 不冒泡,需另寻方案closest() 在 IE 中不支持,如需兼容旧浏览器,可用 polyfill 或手动遍历 parentNode











