什么是事件冒泡和捕获?

事件冒泡和捕获有什么区别? 在这两种模式中,哪种模式更快更好?


事件冒泡和捕获是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元素处理。

有关更多信息,请参阅

  • QuirksMode上的事件顺序
  • MDN上的addEventListener
  • 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());
    }
    
    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