
⭐️ 更多前端技术和知识点,搜索订阅号
JS 菌订阅
梳理下常见的不冒泡事件
UI 事件
- load 异步 不冒泡 ❌
- unload 不冒泡 ❌
- abort 不冒泡 ❌
- error 异步 不冒泡 ❌
- select
load、unload 这些资源加载的事件不冒牌也是容易理解🤐
Focus 事件
事件触发顺序见下表:
| Event Type | Notes |
|---|---|
| User shifts focus | |
| focusin | 第一个目标元素获得焦点之前触发 |
| focus | 第一个目标元素获得焦点之后触发 |
| User shifts focus | |
| focusout | 第一个目标元素失去焦点之前触发 |
| focusin | 第二个目标元素获得焦点之前触发 |
| blur | 第一个目标元素失去焦点之后触发 |
| focus | 第二个元素获得焦点之后触发 |
- blur 不冒泡 ❌
- focus 不冒泡 ❌
- focusin
- focusout
要注意 blur 事件和 focus 事件都是不冒泡的,因获取和失去焦点本身就是针对这个元素的。如果要坚挺具体的焦点变化情况,那么应该使用 focusin 和 focusout
Mouse 事件
如果元素内部没有嵌套另一个元素,事件触发的顺序见下表:
| Event Type | Element | Notes |
|---|---|---|
| mousemove | ||
| 移动到元素A | ||
| mouseover | A | |
| mouseenter | A | |
| mousemove | A | Multiple mousemove events |
| 移出元素A | ||
| mouseout | A | |
| mouseleave | A |
如果元素A内部嵌套了元素B,事件触发顺序见下表:
| Event Type | Element | Notes |
|---|---|---|
| mousemove | ||
| 移动到元素A | ||
| mouseover | A | |
| mouseenter | A | |
| mousemove | A | Multiple mousemove events |
| 移动到内嵌元素B | ||
| mouseout | A | |
| mouseover | B | |
| mouseenter | B | |
| mousemove | B | Multiple mousemove events |
| 重新移动到A | ||
| mouseout | B | |
| mouseleave | B | |
| mouseover | A | |
| mousemove | A | Multiple mousemove events |
| 移出元素A | ||
| mouseout | A | |
| mouseleave | A |
如果是下图所示

直接移动到元素C,常见于失去焦点再获得焦点的情况,事件触发顺序见下表:
| Event Type | Element | Notes |
|---|---|---|
| mousemove | ||
| 直接移动到元素C | ||
| mouseover | C | |
| mouseenter | A | |
| mouseenter | B | |
| mouseenter | C | |
| mousemove | C | Multiple mousemove events |
| 直接移出元素 C... | ||
| mouseout | C | |
| mouseleave | C | |
| mouseleave | B | |
| mouseleave | A |

可以看到 mouseover/mouseout 事件只触发一次,mouseenter/mouseleave 事件触发了三次
然后再看下 click 元素
| Event Type | Notes |
|---|---|
| mousedown | |
| mousemove | OPTIONAL, multiple events, some limits |
| mouseup | |
| click | |
| mousemove | OPTIONAL, multiple events, some limits |
| mousedown | |
| mousemove | OPTIONAL, multiple events, some limits |
| mouseup | |
| click | |
| dblclick |
Mouse 事件中有两个不冒泡事件:
- click
- dblclick
- mousedown
- mouseenter 不冒泡 ❌
- mouseleave 不冒泡 ❌
- mousemove
- mouseout
- mouseover
- mouseup
mouseenter/mouseleave 看这个单词也是跟 focusin/focusout 一样专注于变化,因此这两个不冒泡的事件和 focus 事件作对比也容易理解 🌞
Wheel 事件
wheel 事件是冒泡事件
- wheel 异步
Input 事件
事件触发顺序是 beforeinput,然后是 input,两者都是冒泡事件
- beforeinput
- input
Keyboard 事件
首先触发 keydown 事件,然后是 beforeinput、input,最后是 keyup;如果长时间按住不放,那么则是 keydown 事件、beforeinput 事件和 input 事件
Keyboard 全部是冒泡事件
- keydown
- keyup
Composition 事件
该事件是复合事件,用来处理输入法编辑器的输入。
该事件包括三个:
- compositionstart 输入法编辑器打开状态,准备输入
- compositionupdate 向输入字段插入新字符时触发
- compositionend 输入法编辑器关闭时触发
⚠️ 需要注意的是,三个事件中只有第一个 compositionstart 事件是 cancelable 的,并且三个事件都是冒泡事件
其他
除此之外,还有监听 Node 节点插入移除事件也是不冒泡事件
- DOMNodeInsertedIntoDocument 不冒泡 ❌
- DOMNodeRemovedFromDocument 不冒泡 ❌
另外,html 中表单验证合法性 invalid 事件也是不冒泡的
- invalid 不冒泡 ❌
indexedDB 中的一系列事件也都是不冒泡的,除了 abort 事件
- abort
- blocked 不冒泡 ❌
- close 不冒泡 ❌
- complete 不冒泡 ❌
- success 不冒泡 ❌
- upgradeneeded 不冒泡 ❌
- versionchange 不冒泡 ❌
html5 的媒体事件 media Event 也都是不冒泡的
- play 不冒泡 ❌
- mute 不冒泡 ❌
- 等等
html5 的 online offline、notification、push 等事件也都是不冒泡的;针对特定资源的 Progress 事件如 abort、load、progress、timeout 等等都是不冒泡的
针对特定选区的 selection API 的相关事件 selectionchange 是不冒泡的:
- selectstart
- selectionchange 不冒泡 ❌
SSE 的相关事件也是不冒泡的
html5 的 drag & drop 或 touch 事件则是冒泡的

请关注我的订阅号,不定期推送有关 JS 的技术文章,只谈技术不谈八卦 😊