无法理解addEventListener中的useCapture属性
我在https://developer.mozilla.org/en/DOM/element.addEventListener阅读文章,但无法理解useCapture
属性。 定义有:
如果为true,则useCapture表示用户希望启动捕获。 启动捕获之后,指定types的所有事件将被分派到注册的侦听器,然后被分派到DOM树下的任何EventTargets。 在树中冒泡的事件不会触发指定使用捕获的侦听器。
在这段代码中父事件触发子之前,所以我不能理解它的行为。文件对象有usecapture true,子div有usecapture设置为false,文件usecapture被跟踪。所以为什么文件属性比孩子更喜欢。
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>
可以两次激活事件:开始(“捕捉”)和结束(“冒泡”)。 事件按照如何定义的顺序执行。 说,你定义了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);
警报框将按此顺序popup:
- 2(首先定义,使用
capture=true
) - 4(使用
capture=true
定义第二个) - 1(
capture=false
第一个定义的事件) - 3(
capture=false
第二个定义的事件)
我发现这个图对于理解捕获/目标/冒泡阶段非常有用: http : //www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/events.html#Events-phases
以下,从链接提取的内容。
相
事件按照从树根到此目标节点的path进行分派。 然后可以在目标节点级别或从树中较高的任何目标的祖先处进行处理。 事件分派(也称为事件传播)分三个阶段进行,顺序如下:
- 捕获阶段:将事件从树的根目录调度到目标的祖先,直到目标节点的直接父目录。
- 目标阶段:事件被分派到目标节点。
- 冒泡阶段:将事件从目标节点的直接父节点发送到目标的祖先到树的根节点。
目标的祖先是在事件的最初发送之前确定的。 如果目标节点在调度过程中被移除,或者添加或移除了目标的祖先,则事件传播将始终基于目标节点和在调度之前确定的目标的祖先。
一些事件可能不一定完成DOM事件stream的三个阶段,例如事件只能被定义为一个或两个阶段。 作为一个例子,本规范中定义的事件将总是完成捕获和目标阶段,但有些不会完成冒泡阶段(“冒泡事件”与“非冒泡事件”,另请参阅Event.bubbles属性)。
捕捉事件与泡泡事件
- 捕获事件将在泡泡事件前发送
- 事件传播顺序是
- 家长捕获
- 儿童捕获
- 儿童泡沫
- 父母泡影
( stopPropagation()
将停止stream程)
| A -----------------|--|----------------- | Parent | | | | -------------|--|----------- | | |Children V | | | | ---------------------------- | | | --------------------------------------
演示
<div id="parent"> <div id="children"> Click </div> </div> <script> var parent = document.getElementById('parent'), children = document.getElementById('children'); children.addEventListener('click', function (e) { alert('Children Capture'); // e.stopPropagation(); }, true); children.addEventListener('click', function (e) { alert('Children Bubble'); // 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); </script>
当你说useCapture = true的时候,事件在捕获阶段从上到下执行,如果是false,它会从底部开始。
这一切都是关于事件模型: http : //www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow你可以在冒泡阶段或捕获阶段捕获事件。 你的select。
看看http://www.quirksmode.org/js/events_order.html – 你会发现它非常有用。
代码示例:
<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);
执行:点击Inner Div,警报显示为:Div 2> Div 1
这里的脚本是从内部元素执行的:Event Bubbling(useCapture已被设置为false)
div 1设置为true,div 2设置为false
d1.addEventListener('click',function(){alert("Div 1")},true); d2.addEventListener('click',function(){alert("Div 2")},false);
执行:点击Inner 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);
执行:点击Inner Div,警报显示为:Div 2> Div 1
这里的脚本是从内部元素执行的:Event Bubbling(useCapture已被设置为false)
div 1设置为true,div 2设置为true
d1.addEventListener('click',function(){alert("Div 1")},true); d2.addEventListener('click',function(){alert("Div 2")},true);
执行:点击Inner Div,警报显示为:Div 1> Div 2
这里的脚本是从祖先/外部元素执行的:事件捕获,因为useCapture已经设置为true
鉴于事件旅行的三个阶段:
- 捕获阶段 :将事件从树的根目录调度到目标的祖先,直到目标节点的直接父目录。
- 目标阶段 :事件被分派到目标节点。
- 冒泡阶段 :将事件从目标节点的直接父节点发送到目标的祖先到树的根节点。
useCapture
表示事件将在哪个阶段开始:
如果为
true
,则useCapture表示用户只希望为捕获阶段添加事件侦听器,即在目标阶段和冒泡阶段不会触发此事件侦听器。 如果为false
,事件监听器只会在目标和冒泡阶段被触发
来源与第二个最佳答案相同: https : //www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/events.html#Events-phases
定义的顺序只在项目处于同一级别时才重要。 如果您在代码中反转定义的顺序,则会得到相同的结果。
但是,如果您颠倒了两个事件处理程序的useCapture设置,那么子事件处理程序在父级事件处理程序之前作出响应。 原因在于子事件处理程序现在将在触发阶段之前的捕获阶段被触发,在该阶段中父事件处理程序将被触发。
如果将两个事件处理程序的useCapture设置为true(无论定义的顺序如何),则会首先触发父事件处理程序,因为它处于捕获阶段的子项之前。
相反,如果为两个事件处理程序都将useCapture设置为false(无论定义顺序如何),则会首先触发子事件处理程序,因为它处于冒泡阶段之前。