事件捕獲、事件冒泡

摘抄

當一個DOM事件被觸發時,它不僅僅只是單純地在本身對象上觸發一次,而是會經歷三個不同的階段:

 

  1. 捕獲階段:先由文檔的根節點document往事件觸發對象,從外向內捕獲事件對象;
  2. 目標階段:到達目標事件位置(事發地),觸發事件;
  3. 冒泡階段:再從目標事件位置往文檔的根節點方向回溯,從內向外冒泡事件對象。

來源:https://blog.csdn.net/ywl570717586/article/details/70888020 

正文 

 綁定在被點擊元素的事件是按照代碼順序發生,其他元素通過冒泡或者捕獲“感知”的事件,按照W3C的標準,先發生捕獲事件,後發生冒泡事件。所有事件的順序是:其他元素捕獲階段事件 -> 本元素代碼順序事件 -> 其他元素冒泡階段事件 。

addEventListener函數的第三個參數設置爲true爲捕獲事件,false爲冒泡事件。

 

<body οnlοad="load();">
<div id="d1" style="width: 400px; height: 400px; border: solid 1px;">
    <div id="d2" style="width: 200px; height: 200px; border: solid 1px;">
        <div id="d3" style="width: 100px; height: 100px; border: solid 1px;">one</div>
    </div>
</div>
</body>

栗子1(捕獲)

<script type="text/javascript">
      function load() {
        div1 = document.getElementById("d1");
        div2 = document.getElementById("d2");
        div3 = document.getElementById("d3");

        div1.addEventListener("click", (e) => {
          console.log("div1被點擊,監聽觸發於捕獲階段");
        }, true);
        div2.addEventListener("click", (e) => {
          console.log("div2被點擊,監聽觸發於捕獲階段");
        }, true);
        div3.addEventListener("click", (e) => {
          console.log("div3被點擊,監聽觸發於捕獲階段");
        }, true);    
      }
    </script>

點擊div3 

栗子2(冒泡)

<script type="text/javascript">
      function load() {
        div1 = document.getElementById("d1");
        div2 = document.getElementById("d2");
        div3 = document.getElementById("d3");

        div1.addEventListener("click", (e) => {
          console.log("div1被點擊,監聽觸發於冒泡階段");
        }, false);
        div2.addEventListener("click", (e) => {
          console.log("div2被點擊,監聽觸發於冒泡階段");
        }, false);
        div3.addEventListener("click", (e) => {
          console.log("div3被點擊,監聽觸發於冒泡階段");
        }, false);

      }
 </script>

點擊div3 

栗子3(組合,先設置捕獲,後設置冒泡)

 <script type="text/javascript">
      function load() {
        div1 = document.getElementById("d1");
        div2 = document.getElementById("d2");
        div3 = document.getElementById("d3");

        div1.addEventListener("click", (e) => {
          console.log("div1被點擊,監聽觸發於捕獲階段");
        }, true);
        div2.addEventListener("click", (e) => {
          console.log("div2被點擊,監聽觸發於捕獲階段");
        }, true);
        div3.addEventListener("click", (e) => {
          console.log("div3被點擊,監聽觸發於捕獲階段");
        }, true);

        div1.addEventListener("click", (e) => {
          console.log("div1被點擊,監聽觸發於冒泡階段");
        }, false);
        div2.addEventListener("click", (e) => {
          console.log("div2被點擊,監聽觸發於冒泡階段");
          // e.stopImmediatePropagation();
        }, false);
        div3.addEventListener("click", (e) => {
          console.log("div3被點擊,監聽觸發於冒泡階段");
        }, false);

      }
    </script>

 點擊div3 ,div1和div2不是真正被點擊的目標元素,按照先捕獲後冒泡順序執行。div1和div2的捕獲函數執行以後,輪到div3觸發事件的時候,因爲代碼中先設置的捕獲監聽,後設置的冒泡監聽,所以先觸發了捕獲函數的執行。

栗子4(組合,先設置冒泡,後設置捕獲)

<script type="text/javascript">
      function load() {
        div1 = document.getElementById("d1");
        div2 = document.getElementById("d2");
        div3 = document.getElementById("d3");

        div1.addEventListener("click", (e) => {
          console.log("div1被點擊,監聽觸發於冒泡階段");
        }, false);
        div2.addEventListener("click", (e) => {
          console.log("div2被點擊,監聽觸發於冒泡階段");
        }, false);
        div3.addEventListener("click", (e) => {
          console.log("div3被點擊,監聽觸發於冒泡階段");
        }, false);

        div1.addEventListener("click", (e) => {
          console.log("div1被點擊,監聽觸發於捕獲階段");
        }, true);
        div2.addEventListener("click", (e) => {
          console.log("div2被點擊,監聽觸發於捕獲階段");
        }, true);
        div3.addEventListener("click", (e) => {
          console.log("div3被點擊,監聽觸發於捕獲階段");
        }, true);

      }
</script>

 點擊div3 ,div1和div2不是真正被點擊的目標元素,按照先捕獲後冒泡順序執行。div1和div2的捕獲函數執行以後,輪到div3觸發事件的時候,因爲代碼中先設置的冒泡監聽,後設置的捕獲監聽,所以先觸發了冒泡函數的執行。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章