概括:
该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>首先被触发。这是因为事件现在在捕获阶段而不是冒泡阶段被触发。