我读过https://developer.mozilla.org/en/DOM/element.addEventListener上的文章,但无法理解useCapture属性。定义如下:
如果为true, useCapture表示用户希望发起捕获。在启动捕获之后,指定类型的所有事件将被分派到已注册侦听器,然后再分派到DOM树中它下面的任何EventTargets。在树中向上冒泡的事件不会触发指定使用capture的侦听器。
在这段代码中,父事件在子事件之前触发,所以我无法理解它
的行为。文档对象的usecapcapture设置为true,子div的usecapcapture设置为false,文档usecapcapture紧随其后。为什么document property优先于child。
函数load() {
文档。addEventListener("click", function() {
警报(“父事件”);
},真正的);
. getelementbyid(“div1”)。addEventListener("click", function() {
警报(“孩子事件”);
},假);
}
<身体onload = " load ()" >
<div id="div1">点击我</div>
身体< / >
简介:
DOM规范描述如下:
https://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/events.html#Events-phases
工作方式如下:
事件按照从树的根(文档)到目标节点的路径分派。目标节点是最深的HTML元素,即event.target。事件分派(也称为事件传播)发生在三个阶段,顺序如下:
捕获阶段:将事件从树(文档)的根分发到目标节点的直接父节点。
目标阶段:事件被分派到目标节点。目标阶段始终位于分离事件的最深的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。这是一个布尔值,当设置为true时,允许事件监听器使用事件捕获而不是事件冒泡。
在我们的例子中,当我们将useCapture参数设置为false时,我们看到发生了冒泡事件。首先触发目标阶段的事件(记录innerBubble),然后通过事件冒泡触发父元素中的事件(记录outerBubble)。
当我们将useCapture参数设置为true时,我们看到外部<div>中的事件首先被触发。这是因为事件现在是在捕获阶段而不是冒泡阶段触发的。
捕获事件(useCapture = true) vs泡沫事件(useCapture = false)
MDN参考
Capture Event将在Bubble Event之前分派
事件传播顺序为
父母捕获
孩子捕捉
目标捕获和目标气泡
按登记的顺序
当元素是事件的目标时,useCapture参数不重要(谢谢@bam和@legend80s)
孩子泡沫
父母泡沫
stopPropagation()将停止流
Demo
结果:
父母捕获
目标泡沫1
(因为目标的捕获和气泡将按照它们注册的顺序触发,所以这是优先触发)
目标捕获
目标泡沫2
父母泡沫
var parent = document.getElementById('parent');
var target = document.getElementById('target');
// "target" will trigger in the order of register (addEventListener()), capture / bubble don't affect the order
// #2
target.addEventListener('click', function (e) {
console.log('Target Bubble 1');
// e.stopPropagation();
}, false);
// #3
target.addEventListener('click', function (e) {
console.log('Target Capture');
// e.stopPropagation();
}, true);
// #4
target.addEventListener('click', function (e) {
console.log('Target Bubble 2');
// e.stopPropagation();
}, false);
// #1 : "parent capture" first
parent.addEventListener('click', function (e) {
console.log('Parent Capture');
// e.stopPropagation();
}, true);
// #5 : "parent bubble" last
parent.addEventListener('click', function (e) {
console.log('Parent Bubble');
// e.stopPropagation();
}, false);
<div id="parent">
<button id="target" style="padding: 1em 0.8em;">
Trigger event
</button>
</div>