關於DOM2級事件的事件捕獲和事件冒泡

花一天時間研究完了DOM2級事件中addEventListener的執行機制,做爲開山第一帖,和你們講講多個addEventListener同時添加時的執行前後規律:
圖片描述javascript

如圖,你們都知道,W3c的DOM事件觸發分爲三個階段:
①、事件捕獲階段,即由最頂層元素(通常是從window元素開始,有的瀏覽器是從document開始,至於其中的差異我稍後會更新)開始,逐次進入dom內部,最後到達目標元素,依次執行綁定在其上的事件
②、處於目標階段,檢測機制到達目標元素,按事件註冊順序執行綁定在目標元素上的事件。
③、事件冒泡階段,從目標元素出發,向外層元素冒泡,最後到達頂層(window或document),依次執行綁定再其上的事件。java

在addEventListener中,利用第三個參數控制其是從哪一個階段開始,「true」是從捕獲階段開始,而「false」則是跳過捕獲階段,從冒泡階段開始。
看一個簡單的例子:瀏覽器

<script type="text/javascript">
window.onload=function(){
    var outer = document.getElementById("outer");
    var inner = document.getElementById('inner');

outer.addEventListener("click",   function(){
      alert("1");
    }
, true);

 inner.addEventListener("click",      function(){
      alert("2");
     }
, true);

 outer.addEventListener("click",
     function(){
        alert("3");
    }
,false)   
}
</script>

<body>
    <div id="outer">
        <div id="inner"></div>
    </div>
</body>

在這個例子裏,若是咱們點擊內層元素inner,那麼處於捕獲階段的1最早彈出,接下來是目標元素2彈出,最後是處於冒泡階段的3彈出,即:1,2,3.
即便在代碼裏變換三個綁定事件的順序,只要點擊的是inner,這個執行順序就不會變。dom

那麼問題來了,若是點擊的是外層outer的話呢?spa

要明白這個問題,咱們必須明確一點:目標事件在哪一層,事件流就在哪一層迴流,即便在outer事件下還有許多子孫節點,事件流都不會在outer以後往內流,此時,inner上的事件不會被觸發,所以在這段代碼中,只會彈出1和3。code

那麼這兩個數字哪一個先彈呢?因爲此時事件處於第二階段,即「處於目標階段」,彈出順序取決的也再也不是捕獲或冒泡,而是誰在代碼中先註冊,所以,在這段代碼中,彈出的是:1→3.blog

綜上所述,事件在DOM中的執行順序爲:外層捕獲事件→內層捕獲事件→先註冊的目標事件→後註冊的目標事件→內層冒泡事件→外層冒泡事件事件

讓咱們再看個例子來加深這個概念:圖片

<script type="text/javascript">
window.onload=function(){
    var outer = document.getElementById("outer");
    var inner = document.getElementById('inner');
    var oBox=document.getElementById('box');
    
    oBox.addEventListener("click",function(){
        alert('1');
    },true)
    oBox.addEventListener("click",function(){
        alert('4');
    },false)
    

    outer.addEventListener("click", function(){
      alert("2");
    }, true);

    
    inner.addEventListener("click",function(){
        alert('3.2')
    },false)
    

    inner.addEventListener("click", function(){
      alert("3.1");
     }, true);
    
}
</script>

<body>
    <div id="box">
        <div id="outer">
            <div id="inner"></div>
        </div>
    </div>
</body>

在這段代碼裏,box上的捕獲事件最早執行,而後是outer上的捕獲事件,而後是inner上先註冊的事件,而後是inner上後註冊的事件,最後是box上的冒泡事件
彈出順序爲:1→2→3.2→3.1→4 ip

補充一點,在ie8-中,因爲addEventLister不起做用,咱們使用attachEvent方法來綁定事件,此時在第二階段,也就是處於目標階段,若是目標元素上綁定了兩個事件,那麼其執行順序和addEventLister相反:誰後註冊誰先執行。

相關文章
相關標籤/搜索