跳到正文

DOM 事件与事件委托 ​

  • 状态:未准备
  • 适用方向:前端 / Go 全栈
  • 最近复习:待填写
  • 下次复习:待安排

一句话回答 ​

DOM 事件沿事件路径经历捕获、目标和可能的冒泡阶段;事件委托把子项处理集中到祖先,通过事件目标识别操作,适合动态列表。

原理解释 ​

event.target 是事件目标(跨 Shadow DOM 时可能重定向);event.currentTarget 是当前监听器所在节点。默认监听冒泡侧,capture:true 监听捕获侧。并非所有事件都冒泡,例如 focus 不冒泡,可用捕获监听或 focusin。

js
const list = document.querySelector('#list')
function onClick(event) {
  if (!(event.target instanceof Element)) return
  const button = event.target.closest('button[data-id]')
  if (!button || !list.contains(button)) return
  console.log(button.dataset.id)
}
list.addEventListener('click', onClick)
// 清理时使用相同函数引用、匹配 capture
// list.removeEventListener('click', onClick)

closest 解决点击按钮内部图标的问题;contains 避免向上匹配到委托范围之外。

场景与边界 ​

  • preventDefault() 阻止可取消事件的默认行为,不阻止传播。
  • stopPropagation() 阻止后续传播,不自动阻止同一节点其他监听器;后者需 stopImmediatePropagation。
  • passive:true 表示不调用 preventDefault,适用于无需阻止默认行为的监听,不能在其中再有效取消默认行为。
  • once:true 表示首次触发后自动移除;AbortSignal 可统一管理一组监听器。

项目中的应用 ​

沿 Blog 目录监听 检查监听注册和卸载是否成对;事件委托例子是学习实现,不表示该项目使用了委托。

常见追问 ​

  • 委托一定更快吗? 它减少监听器数量,但增加匹配和路径判断;应看列表规模与实际交互。
  • 滚动监听里 passive 等于节流吗? 不等于;passive 是取消默认行为的承诺,回调中的大量工作仍会占用主线程。
  • React onClick 等于原生监听吗? React 提供自己的事件抽象,涉及委托和版本差异,不能照搬原生节点绑定模型。

参考资料 ​

理解机制,讲清取舍,用复盘检验掌握。