EventTarget.addEventListener() 的 useCapture 参数使用?

EventTarget.addEventListener()'s useCapture argument use?

我正在研究 vanilla JavaScript,我在理解 EventTarget.addEventListener() 函数中这个 useCapture 参数的用途时遇到了一些困难。

https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener

useCapture Optional

If true, useCapture indicates that the user wishes to initiate capture. After initiating capture, all events of the specified type will be dispatched to the registered listener before being dispatched to any EventTarget beneath it in the DOM tree. Events which are bubbling upward through the tree will not trigger a listener designated to use capture. See DOM Level 3 Events and JavaScript Event order for a detailed explanation. If not specified, useCapture defaults to false.

阅读它的文档,我对第一句话感到困惑。和 试图理解它我已经设置了一个包含三个嵌套元素的小测试页面,在最上面的两个元素上有一个点击监听器 div.

代码:

var treeTopEl = document.getElementById('container');
var treeMiddleEl = document.getElementById('wrapper');

var output = document.getElementById('output');

var treeTopElListener = function(event){
 var elId = event.target.id;
 output.innerHTML += "\nListener on the top element was triggerd,\n\t The event target id is : "+elId; 
};

var treeMiddleElListener = function(event){
 var elId = event.target.id;
 output.innerHTML += "\nListener on the middle element was triggerd,\n\tThe event target id is : "+elId; 
};

treeTopEl.addEventListener('click', treeTopElListener, false);
treeMiddleEl.addEventListener('click', treeMiddleElListener, true);
#container, #wrapper {
  padding : 20px;
  border : 1px solid green;
}
<div id="container">
 <div id="wrapper">
   <button id="testBtn">A button</button>

 </div>
</div>
<pre id="output"></pre>

问题:

当您单击按钮时,无论 useCapture 配置如何,都会触发两个侦听器 以相同的顺序 :两个 truefalse;第一个 true,第二个 false;第一个 false,第二个 true.

究竟是什么捕获了 useCapture 标志?

我认为来自 the DOM events specification 的这张图表几乎说明了一切:

基本上:useCapture 参数用于在捕获阶段而不是冒泡阶段接收通知。捕获阶段处理程序将在 any 冒泡阶段处理程序之前被调用。请注意,IE9 之前的 Internet Explorer 不支持捕获阶段。

所以一个更好的例子是在同一个元素上的两个处理程序,在中间(但为了完整性让我们做所有三个级别):

hook("container", "- ");
hook("wrapper",   "&nbsp;&nbsp;- ");
hook("testBtn",   "&nbsp;&nbsp;&nbsp;&nbsp;- ");

function hook(id, prefix) {
  var element = document.getElementById(id);
  element.addEventListener("click", function(e) {
    display(id + "'s capturing handler called", prefix);
  }, true);
  element.addEventListener("click", function(e) {
    display(id + "'s bubbling called", prefix);
  }, false);
}

function display(msg, prefix) {
  var p = document.createElement('p');
  p.innerHTML = (prefix || "") + msg;
  document.body.appendChild(p);
}
#container, #wrapper {
  padding : 10px;
  border : 1px solid green;
}
p {
  font-family: sans-serif;
  padding: 0;
  margin: 0;
}
<div id="container">
 <div id="wrapper">
   <button id="testBtn">A button</button>
 </div>
</div>