什么是事件冒泡和捕获?
事件冒泡和捕获有什么区别? 在这两种模式中,哪种模式更快更好?
事件冒泡和捕获是HTML DOM API中事件传播的两种方式,其中一个事件发生在另一个元素内的元素中,并且这两个元素都为该事件注册了一个句柄。 事件传播模式确定元素以什么顺序接收事件。
冒泡时,事件首先被最内层的元素捕获并处理,然后传播到外层元素。
捕获时,事件首先被最外层的元素捕获并传播到内层元素。
捕捉也被称为“滴答”,这有助于记住传播顺序:
滴下来,起泡
早在过去,网景主张事件捕获,而微软则推动事件冒泡。 两者都是W3C文档对象模型事件标准(2000)的一部分。
IE <9只使用事件冒泡,而IE9 +和所有主流浏览器均支持。 另一方面,对于复杂的DOM,事件冒泡的性能可能会略低。
我们可以使用addEventListener(type, listener, useCapture)
以冒泡(默认)或捕获模式注册事件处理程序。 要使用捕获模型,请将第三个参数作为true
。
例
<div>
<ul>
<li></li>
</ul>
</div>
在上面的结构中,假设li
元素中发生了点击事件。
在拍摄模式下,事件将被处理div
第一(单击事件处理程序div
将触发第一个),然后在ul
,然后在最后的目标元素, li
。
在冒泡模型中,会发生相反的情况:事件首先由li
处理,然后由ul
,最后由div
元素处理。
有关更多信息,请参阅
在下面的示例中,如果单击任何突出显示的元素,可以看到事件传播流的捕获阶段首先出现,然后是冒泡阶段。
var logElement = document.getElementById('log');
function log(msg) {
logElement.innerHTML += ('<p>' + msg + '</p>');
}
function capture() {
log('capture: ' + this.firstChild.nodeValue.trim());
}
function bubble() {
log('bubble: ' + this.firstChild.nodeValue.trim());
}
var divs = document.getElementsByTagName('div');
for (var i = 0; i < divs.length; i++) {
divs[i].addEventListener('click', capture, true);
divs[i].addEventListener('click', bubble, false);
}
p {
line-height: 0;
}
div {
display:inline-block;
padding: 5px;
background: #fff;
border: 1px solid #aaa;
cursor: pointer;
}
div:hover {
border: 1px solid #faa;
background: #fdd;
}
<div>1
<div>2
<div>3
<div>4
<div>5</div>
</div>
</div>
</div>
</div>
<section id="log"></section>
描述:
quirksmode.org对此有很好的描述。 简而言之(从quirksmode复制):
事件捕获
当你使用事件捕获
| |
---------------| |-----------------
| element1 | | |
| -----------| |----------- |
| |element2 / | |
| ------------------------- |
| Event CAPTURING |
-----------------------------------
element1的事件处理程序首先触发,element2的事件处理程序最后触发。
事件冒泡
当你使用事件冒泡
/
---------------| |-----------------
| element1 | | |
| -----------| |----------- |
| |element2 | | | |
| ------------------------- |
| Event BUBBLING |
-----------------------------------
element2的事件处理程序首先触发,element1的事件处理程序最后触发。
要使用什么?
这取决于你想要做什么。 没有更好的了。 区别在于事件处理程序的执行顺序。 大多数情况下,在冒泡阶段触发事件处理程序将会很好,但也可能需要提前触发它们。
如果元素1和元素2有两个元素。元素2位于元素1内部,我们附加一个事件处理函数,两个元素都可以说onClick。 现在当我们点击元素2时,两个元素的eventHandler将被执行。 现在问题在于事件的执行顺序。 如果附加元素1的事件首先执行,则称为事件捕获,如果附加元素2的事件首先执行,则称为事件冒泡。 按照W3C的规定,事件将在捕获阶段开始,直到它到达目标回到元素,然后开始冒泡
捕获和冒泡状态由addEventListener方法的useCapture参数所知
eventTarget.addEventListener(类型,听众,[方法,useCapture]);
默认情况下,useCapture为false。 这意味着它处于冒泡阶段。
var div1 = document.querySelector("#div1");
var div2 = document.querySelector("#div2");
div1.addEventListener("click", function (event) {
alert("you clicked on div 1");
}, true);
div2.addEventListener("click", function (event) {
alert("you clicked on div 2");
}, false);
#div1{
background-color:red;
padding: 24px;
}
#div2{
background-color:green;
}
<div id="div1">
div 1
<div id="div2">
div 2
</div>
</div>
链接地址: http://www.djcxy.com/p/83715.html
上一篇: What is event bubbling and capturing?
下一篇: Wait till a Function with animations is finished until running another Function