我在https://developer.mozilla.org/en/DOM/element.addEventListener阅读了文章,但无法理解useCapture
属性。定义有:
如果为true,则useCapture表示用户希望启动捕获。启动捕获后,指定类型的所有事件将被分派到已注册的侦听器,然后再分派到DOM树中它下面的任何EventTargets。向上冒泡树的事件不会触发指定使用捕获的侦听器。
在此代码中,父事件在子事件之前触发,因此我无法理解它 behavior.Document对象有usecapture为true,子div有usecapture设置为false,文件usecapture被跟踪。所以为什么文档属性比child更受欢迎。
function load() {
document.addEventListener("click", function() {
alert("parent event");
}, true);
document.getElementById("div1").addEventListener("click", function() {
alert("child event");
}, false);
}
<body onload="load()">
<div id="div1">click me</div>
</body>
答案 0 :(得分:327)
可以在两种情况下激活事件:开始(“捕获”)和结束(“冒泡”)。 事件按照它们的定义顺序执行。比如说,你定义了4个事件监听器:
window.addEventListener("click", function(){alert(1)}, false);
window.addEventListener("click", function(){alert(2)}, true);
window.addEventListener("click", function(){alert(3)}, false);
window.addEventListener("click", function(){alert(4)}, true);
警告框将按以下顺序弹出:
2
(首先定义,使用capture=true
)4
(使用capture=true
定义第二个)1
(首次定义的事件为capture=false
)3
(第二个定义的事件capture=false
)答案 1 :(得分:248)
我发现此图对于理解捕获/目标/泡沫阶段非常有用: http://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/events.html#Events-phases
下面是从链接中提取的内容。
<强>阶段强>
按照从树的根到此目标节点的路径调度事件。然后可以在目标节点级别本地处理它,或者从树中较高的任何目标的祖先处理它。事件调度(也称为事件传播)分三个阶段发生,顺序如下:
目标的祖先在事件的初始发送之前确定。如果在调度期间删除了目标节点,或者添加或删除了目标的祖先,则事件传播将始终基于目标节点和在调度之前确定的目标的祖先。
某些事件可能不一定完成DOM事件流的三个阶段,例如该事件只能定义为一个或两个阶段。例如,本规范中定义的事件将始终完成捕获和目标阶段,但有些事件不会完成冒泡阶段(“冒泡事件”与“非冒泡事件”,另请参见Event.bubbles属性)。
答案 2 :(得分:69)
useCapture = true
)vs泡泡事件(useCapture = false
)useCapture
参数无关紧要(谢谢@bam和@ legend80s) stopPropagation()
将停止流程
结果:
儿童捕获
(因为儿童是目标,因此捕获和泡泡将按照他们注册的顺序触发)
var parent = document.getElementById('parent'),
children = document.getElementById('children');
children.addEventListener('click', function (e) {
alert('Children Bubble 1');
// e.stopPropagation();
}, false);
children.addEventListener('click', function (e) {
alert('Children Capture');
// e.stopPropagation();
}, true);
children.addEventListener('click', function (e) {
alert('Children Bubble 2');
// e.stopPropagation();
}, false);
parent.addEventListener('click', function (e) {
alert('Parent Capture');
// e.stopPropagation();
}, true);
parent.addEventListener('click', function (e) {
alert('Parent Bubble');
// e.stopPropagation();
}, false);
<div id="parent">
<div id="children">
Click
</div>
</div>
答案 3 :(得分:14)
当你说useCapture = true时,事件在捕获阶段从上到下执行,当为false时,它会从底部到顶部执行冒泡。
答案 4 :(得分:11)
代码示例:
<div id="div1" style="background:#9595FF">
Outer Div<br />
<div id="div2" style="background:#FFFFFF">
Inner Div
</div>
</div>
Javascript代码:
d1 = document.getElementById("div1");
d2 = document.getElementById("div2");
如果两者都设置为false
d1.addEventListener('click',function(){alert("Div 1")},false);
d2.addEventListener('click',function(){alert("Div 2")},false);
执行:点击内部Div,警报显示为: Div 2> Div 1
这里脚本是从内部元素执行的:事件冒泡(useCapture已设置为false)
div 1设置为true,div 2设置为false
d1.addEventListener('click',function(){alert("Div 1")},true);
d2.addEventListener('click',function(){alert("Div 2")},false);
执行:点击内部Div,警报显示为: Div 1> Div 2
这里的脚本是从祖先/外部元素执行的:事件捕获(useCapture已设置为true)
div 1设置为false,div 2设置为true
d1.addEventListener('click',function(){alert("Div 1")},false);
d2.addEventListener('click',function(){alert("Div 2")},true);
执行:点击内部Div,警报显示为: Div 2> Div 1
这里脚本是从内部元素执行的:事件冒泡(useCapture已设置为false)
div 1设置为true,div 2设置为true
d1.addEventListener('click',function(){alert("Div 1")},true);
d2.addEventListener('click',function(){alert("Div 2")},true);
执行:点击内部Div,警报显示为: Div 1> Div 2
此处脚本从祖先/外部元素执行:事件捕获,因为useCapture已设置为true
答案 5 :(得分:10)
关于事件模型的全部内容:http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow
您可以在冒泡阶段或捕获阶段捕获事件。你的选择。
看看http://www.quirksmode.org/js/events_order.html - 你会发现它非常有用。
答案 6 :(得分:6)
鉴于事件旅行的三个阶段:
- 捕获阶段:将事件从树的根目录分配给目标的祖先到目标的直接父级 节点
- 目标阶段:将事件分派到目标节点。
- 冒泡阶段:将事件从目标节点的直接父节点分配给目标的祖先到根节点 树。
醇>
useCapture
表示旅行的活动将在哪个阶段:
如果
true
, useCapture 表示用户希望添加活动 仅捕获阶段的侦听器,即此事件侦听器不会 在目标和冒泡阶段被触发。如果是false
,那么 事件侦听器只会在目标和冒泡期间触发 相
来源与第二个最佳答案相同:https://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/events.html#Events-phases
答案 7 :(得分:5)
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
时允许事件监听器使用事件捕获而不是事件冒泡。
在我们的示例中,当将useCapture参数设置为false
时,我们看到事件冒泡发生了。首先触发目标阶段的事件(记录innerBubble),然后通过事件冒泡触发父元素中的事件(记录externalBubble)。
当我们将useCapture参数设置为true
时,我们看到外部<div>
中的事件首先被触发。这是因为该事件现在是在捕获阶段而不是冒泡阶段触发的。
答案 8 :(得分:1)
定义的顺序仅在项目处于同一级别时才有意义。如果您颠倒代码中的定义顺序,您将得到相同的结果。
但是,如果在两个事件处理程序上反转useCapture设置,则子事件处理程序将在父事件处理程序之前响应。这样做的原因是现在将在捕获阶段触发子事件处理程序,该阶段在将触发父事件处理程序的冒泡阶段之前。
如果将两个事件处理程序的useCapture设置为true - 无论定义顺序如何 - 将首先触发父事件处理程序,因为它在捕获阶段处于子代之前。
相反,如果将两个事件处理程序的useCapture设置为false - 无论定义的顺序如何 - 将首先触发子事件处理程序,因为它在冒泡阶段的父级之前。