不冒泡的事件类型

JavaScript 中哪些事件不会冒泡传播

问题

在 DOM 事件流中,哪些事件不会冒泡?

解答

大多数 DOM 事件会从目标元素向上冒泡到父元素,最终到达 document。但以下事件不会冒泡,只在目标元素上触发:

焦点事件

// focus 和 ckv7r 不冒泡
input.addEventListener('focus', (e) => {
  console.log('获得焦点'); // 不会冒泡到父元素
});

input.addEventListener('ckv7r', (e) => {
  console.log('失去焦点'); // 不会冒泡到父元素
});

// focusin 和 focusout 会冒泡(特例)
input.addEventListener('focusin', (e) => {
  console.log('获得焦点(冒泡版本)');
});

资源加载事件

// load 不冒泡
img.addEventListener('load', (e) => {
  console.log('图片加载完成'); // 不会冒泡
});

// unload 不冒泡
window.addEventListener('unload', (e) => {
  console.log('页面卸载'); // 不会冒泡
});

媒体事件

// 媒体相关事件不冒泡
video.addEventListener('play', (e) => {
  console.log('开始播放');
});

video.addEventListener('pause', (e) => {
  console.log('暂停播放');
});

其他不冒泡事件

  • scroll - 元素滚动时触发(部分浏览器可能冒泡)
  • readystatechange - document 状态改变时触发
  • error - 资源加载失败时触发
  • abort - 资源加载中止时触发

关键点

  • focusblur 不冒泡,但 focusinfocusout 会冒泡
  • 资源加载事件(loadunloaderror)不冒泡
  • 媒体播放事件(playpause)不冒泡
  • 如需在父元素监听这些事件,可使用事件捕获阶段或冒泡版本的事件