事件冒泡和捕获有什么区别?什么时候应该使用冒泡和捕获?
最佳答案
事件冒泡和捕获是 HTML DOM API 中事件传播的两种方式,当一个事件发生在另一个元素内的一个元素中,并且两个元素都注册了该事件的句柄时。事件传播模式在 which order the elements receive the event 中确定.
通过冒泡,事件首先由最里面的元素捕获和处理,然后传播到外部元素。
通过捕获,事件首先被最外面的元素捕获并传播到内部元素。
捕获也称为“trickling”,这有助于记住传播顺序:
trickle down, bubble up
过去,Netscape 提倡事件捕获,而 Microsoft 则提倡事件冒泡。两者都是 W3C Document Object Model Events 的一部分标准(2000)。
IE < 9 使用only event bubbling ,而 IE9+ 和所有主要浏览器都支持两者。另一方面,performance of event bubbling may be slightly lower对于复杂的 DOM。
我们可以使用addEventListener(type,listener,useCapture)
在冒泡(默认)或捕获模式下注册事件处理程序。要使用捕获模型,请将第三个参数传递为 true
。
示例
<div>
<ul>
<li></li>
</ul>
</div>
在上面的结构中,假设在 li
元素中发生了单击事件。
在捕获模型中,事件将首先由 div
处理(div
中的单击事件处理程序将首先触发),然后在 ul
,然后是目标元素的最后一个 li
。
在冒泡模型中,会发生相反的情况:事件将首先由 li
处理,然后由 ul
处理,最后由 div
元素。
欲了解更多信息,请参阅
- Event Order在 QuirksMode 上
- addEventListener在 MDN 上
- Events Advanced在 QuirksMode 上
在下面的示例中,如果单击任何突出显示的元素,您可以看到事件传播流的捕获阶段首先发生,然后是冒泡阶段。
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());
}
function clearOutput() {
logElement.innerHTML = "";
}
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);
}
var clearButton = document.getElementById('clear');
clearButton.addEventListener('click', clearOutput);
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>
<button id="clear">clear output</button>
<section id="log"></section>
关于javascript - 什么是事件冒泡和捕获?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33181394/