什么是事件冒泡和捕获?

2022-08-29 22:05:08

事件冒泡和捕获之间有什么区别?什么时候应该使用冒泡与捕获?


答案 1

事件冒泡和捕获是 HTML DOM API 中的两种事件传播方式,当一个事件发生在另一个元素内的一个元素中,并且两个元素都为该事件注册了句柄时。事件传播模式确定元素接收事件的顺序

使用冒泡时,事件首先由最里面的元素捕获和处理,然后传播到外部元素。

通过捕获,事件首先由最外层的元素捕获并传播到内部元素。

捕获也称为“涓滴”,这有助于记住传播顺序:

涓滴下,气泡向上

回到过去,网景提倡事件捕获,而微软则提倡事件冒泡。两者都是 W3C 文档对象模型事件标准 (2000) 的一部分。

IE < 9 仅使用事件冒泡,而 IE9+ 和所有主流浏览器都支持这两种功能。另一方面,对于复杂的 DOM,事件冒泡的性能可能略低

我们可以在冒泡(默认)或捕获模式下使用 to 注册事件处理程序。要使用捕获模型,请将第三个参数作为 传递。addEventListener(type, listener, useCapture)true

<div>
    <ul>
        <li></li>
    </ul>
</div>

在上面的结构中,假定元素中发生了单击事件。li

在捕获模型中,事件将由第一个(单击事件处理程序中的将首先触发)处理,然后在 ,然后在目标元素中的最后一个处理。divdivulli

在冒泡模型中,将发生相反的情况:事件将首先由 处理 ,然后由 处理,最后由元素处理。liuldiv

有关详细信息,请参阅

在下面的示例中,如果单击任何突出显示的元素,则可以看到事件传播流的捕获阶段首先发生,然后是冒泡阶段。

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>

JSFiddle的另一个例子


答案 2

描述:

quirksmode.org 对此有很好的描述。简而言之(从quirksmode复制):

事件捕获

使用事件捕获时

               | |
---------------| |-----------------
| element1     | |                |
|   -----------| |-----------     |
|   |element2  \ /          |     |
|   -------------------------     |
|        Event CAPTURING          |
-----------------------------------

element1 的事件处理程序首先触发,element2 的事件处理程序最后触发。

事件冒泡

使用事件冒泡时

               / \
---------------| |-----------------
| element1     | |                |
|   -----------| |-----------     |
|   |element2  | |          |     |
|   -------------------------     |
|        Event BUBBLING           |
-----------------------------------

element2 的事件处理程序首先触发,element1 的事件处理程序最后触发。


使用什么?

这取决于你想做什么。没有比这更好的了。不同之处在于事件处理程序的执行顺序。大多数情况下,在冒泡阶段触发事件处理程序是可以的,但也有必要更早地触发它们。