Spirit帶你徹底了解事件捕獲和冒泡機制


Dom標准事件模型

在Dom標准事件模型中,事件是先進行捕獲,達到目標階段時,在進行冒泡的

捕獲階段==>目標階段==>冒泡階段

image-20210914235653177

目標元素和非目標元素

在介紹事件捕獲和事件冒泡前

我們先要了解一下目標元素和非目標元素是什么意思

  • 目標元素:它是我們當前觸發事件的元素
  • 非目標元素:它是在捕獲階段或着冒泡階段中因為綁定了同類型的事件而觸發的元素
  • 每個Dom元素可以綁定多個事件,前提是使用addEvenetListener去添加事件,即使是相同的事件,也可以重復綁定.

事件捕獲

從頁面的根元素開始 一層一層的往下尋找

可以看下我在最上面畫的那張圖

事件冒泡

從目標元素一直往上尋找

可以看下我在最上面的那張圖

addEventListener

addEventListener可以傳入第三個參數useCapture,默認是false

其實還有一個option參數可以傳遞,但是我沒細看,因為目前我看了,我也不知道應用場景,所以打算有需求了,后面在看

  • useCapture參數會false時,默認是捕獲階段 不會觸發事件監聽,會在冒泡階段觸發事件監聽
  • useCapture參數會true時,事件監聽時從捕獲階段開始,但是冒泡階段不會觸發事件監聽

舉例說明

現在我們來分析一道題, 布局代碼都在下面了

HTML代碼

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<style>
    .c {
        width: 200px;
        height: 200px;
        background-color: orange;
    }
</style>

<body>
    <div class="a">
        a
        <div class="b">
            b
            <div class="c">c</div>
        </div>
    </div>
</body>
    
<script src="./script.js"></script>
</html>

JS代碼

const a = document.querySelector(".a");
const b = document.querySelector(".b");
const c = document.querySelector(".c");




a.addEventListener("mousedown", () => {
    alert("彈出a");
}, false)
b.addEventListener("mousedown", (e) => {
    alert("彈出b");
}, true)

c.addEventListener("mousedown", (e) => {
    console.log(e)
    alert("mousedown2");
}, true)
c.addEventListener("mousedown", (e) => {
    alert("mousedown1");
}, false)
c.addEventListener("mousedown", (e) => {
    console.log(e)
    alert("mousedown3");
}, false)
c.addEventListener("mousedown", (e) => {
    console.log(e)
    alert("mousedown4");
}, true)

分析

  1. 從HTML來看,嵌套層級是 a>b>c

  2. 現在來看JS代碼

  3. a,b,c都綁定了mousedown事件,我們仔細看下,這個的執行順序是怎么樣的?

  4. 我可以在給你們分析一下

  5. 對於同一個元素,綁定多個事件,無論是一樣的事件,還是不一樣的事件,只要是觸發了對應事件的監聽器,那么它都會執行

  6. 那么同一個事件的執行順序是怎么樣的呢?

  7. 同一個事件的執行順序是根據定義的順序來執行的,前提是useCapture保持一致

  8. 當我們點擊目標元素時,我們是處於目標階段的,而不是處於冒泡階段或者捕獲階段,這一句話請牢牢記住

  9. 處於目標階段時,當useCapture有true,又有false的階段時
    這個時候 我們可以理解為目標元素其實是形成了一個類似於Dom事件模型的東西.
    在這個模型內,也有捕獲階段和冒泡階段.
    所以如果有true的話,會先執行捕獲階段,按照定義順序
    然后執行fasle階段,也就是冒泡階段,按照事件的定義順序

  10. 所以在目標階段執行的時候,這么多事件的執行順序就是 mousedown2 mousedown4 mousedown1 mousedown3

  11. 那么我們現在可以看下這個整個HTML頁面,這個執行順序是什么樣的呢?

  12. 其實和目標階段的執行是一樣的
    非目標元素的useCapture為true時,捕獲階段會先執行事件監聽
    非目標元素的useCapture為false時,會在捕獲階段和目標階段執行完畢后,在冒泡階段執行事件監聽
    舉個例子,如果我在b身上也綁定了多個相同類型的事件,在有true,有false的情況下,它會先執行true的,false的不會等true執行完畢后就立馬執行,而是等待目標階段執行完畢后,才繼續執行
    大家如果不信的,可以自己去嘗試一下

  13. 所以整體的執行順序是

    b mousedown2 mousedown4 mousedown1 mousedown3 a

圖解

我怕大家還是不明白我說的是什么意思
所以我畫了這張圖,把這個過程給大家詳細介紹一下

image-20210915110603594


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM