哪些事件不冒泡?mouseenter、mouseover 与事件委托有什么区别?

先理解原理和示例,再练习完整口述与追问。

捕获、目标、冒泡;focus/blur 与 focusin/out;enter/leave 与 over/out;target/currentTarget/relatedTarget;原生与框架事件区分。

事件传播按事件自身规则执行,不是所有事件都会冒泡。focus/blur 通常不冒泡,但可使用捕获监听,或选择会冒泡的 focusin/focusout。mouseenter/mouseleave 不冒泡,强调进入离开相关区域;mouseover/mouseout 会冒泡,指针在后代之间移动也可能触发,需要结合 relatedTarget 判断是否真正跨出目标区域。scroll 与 load 等也需按具体目标和规范处理,不能背一份混杂不同环境的清单。

委托把处理器放在祖先,通过 target 找实际动作节点;currentTarget 是当前处理器所属节点。Shadow DOM、composed 以及 React 合成事件等还有额外规则,应区分讨论。

js
function delegateClick(container, onSelect) {
  function handle(event) {
    if (!(event.target instanceof Element)) return
    const button = event.target.closest('button[data-id]')
    if (button && container.contains(button)) onSelect(button.dataset.id)
  }
  container.addEventListener('click', handle)
  return () => container.removeEventListener('click', handle)
}

点击按钮内部图标也能找到按钮,新增后代不必重新绑定。清理函数保证组件销毁后不保留外部引用。

stopPropagation 不等于 preventDefault,捕获可被监听不等于事件会冒泡。用 contains 判断还要考虑嵌套容器的业务归属。

我按事件的原生传播规则选方案:普通点击可委托,焦点用捕获或 focusin/out,进入离开关注 enter/leave 与 relatedTarget。处理器区分目标与绑定节点,并提供清理,不把框架事件行为当全部原生规则。