概括:
该DOM
规范中描述:
https://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/events.html#Events-phases
工作方式如下:
沿着从document
树的根 ( ) 到目标节点的路径调度事件。目标节点是最深的HTML
元素,即 event.target。事件分派(也称为事件传播)分三个阶段和以下顺序发生:
- 捕获阶段:将事件从树的根(
document
)到目标节点的直接父节点分派给目标的祖先。
- 目标阶段:将事件分派到目标节点。目标阶段总是在
html
事件被调度的最深的元素上。
- 冒泡阶段:从目标节点的直接父节点到树的根节点,将事件分派给目标的祖先。
例子:
// bubbling handlers, third argument (useCapture) false (default)
document.getElementById('outerBubble').addEventListener('click', () => {
console.log('outerBubble');
}, false)
document.getElementById('innerBubble').addEventListener('click', () => {
console.log('innerBubble');
}, false)
// capturing handlers, third argument (useCapture) true
document.getElementById('outerCapture').addEventListener('click', () => {
console.log('outerCapture');
}, true)
document.getElementById('innerCapture').addEventListener('click', () => {
console.log('innerCapture');
}, true)
div:hover{
color: red;
cursor: pointer;
}
<!-- event bubbling -->
<div id="outerBubble">
<div id="innerBubble">click me to see Bubbling</div>
</div>
<!-- event capturing -->
<div id="outerCapture">
<div id="innerCapture">click me to see Capturing</div>
</div>
上面的例子确实说明了事件冒泡和事件捕获之间的区别。使用 来添加事件侦听器时addEventListener
,还有第三个元素,称为 useCapture。boolean
当设置true
为时,此 a允许事件侦听器使用事件捕获而不是事件冒泡。
在我们的示例中,当我们将 useCapture 参数设置为时,false
我们会看到事件冒泡发生。首先触发目标阶段的事件(记录innerBubble),然后通过事件冒泡触发父元素中的事件(记录outerBubble)。
当我们将 useCapture 参数设置为 时,true
我们会看到外部事件<div>
首先被触发。这是因为事件现在在捕获阶段而不是冒泡阶段被触发。