JS事件流模型


JS事件流模型

事件捕獲Event Capturing是一種從上而下的傳播方式,以click事件為例,其會從最外層根節向內傳播到達點擊的節點,為從最外層節點逐漸向內傳播直到目標節點的方式。
事件冒泡Event Bubbling是一種從下往上的傳播方式,同樣以click事件為例,事件最開始由點擊的節點,然后逐漸向上傳播直至最高層節點。

DOM0級模型

也稱為原始事件模型,這種方式較為簡單且兼容所有瀏覽器,但是卻將界面與邏輯耦合在一起,可維護性差。

實例

當點擊idi3<div>時,瀏覽器會依次彈出2 1 0

<!DOCTYPE html>
<html>
<head>
    <title>JS事件流模型</title>
</head>
<style type="text/css">
    div{
        display: flex;
        justify-content: center;
        align-items: center;
    }
</style>

<body>
    <div id="i1" style="height: 150px;width: 150px;background: red;" onclick="alert(0)">
        <div id="i2" style="height: 100px;width: 100px;background: green;" onclick="alert(1)">
            <div id="i3" style="height: 50px;width: 50px;background: blue;" onclick="alert(2)"></div>
        </div>
    </div>
</body>
</html>

IE事件模型

IE8及之前的版本是不支持捕獲事件的,IE事件模型共有兩個過程:
事件處理階段target phase,事件到達目標元素, 觸發目標元素的監聽事件。
事件冒泡階段bubbling phase事件從目標元素冒泡到document,依次執行經過的節點綁定的事件。

DOM2級模型

DOM2事件模型是W3C制定的標准模型,支持捕獲型事件和冒泡型事件,調用事件的處理階段依次為捕獲、目標、冒泡。

實例

當點擊idi3<div>時,瀏覽器會依次彈出0 1 3 2addEventListener方法的第三個參數為聲明綁定的事件為捕獲型還是冒泡型,默認為false,也就是冒泡型。

<!DOCTYPE html>
<html>
<head>
    <title>JS事件流模型</title>
</head>
<style type="text/css">
    div{
        display: flex;
        justify-content: center;
        align-items: center;
    }
</style>

<body>
    <div id="i1" style="height: 150px;width: 150px;background: red;">
        <div id="i2" style="height: 100px;width: 100px;background: green;">
            <div id="i3" style="height: 50px;width: 50px;background: blue;"></div>
        </div>
    </div>
</body>

<script type="text/javascript">
    document.addEventListener('click',(e) => {
        alert(0);
    },true) 
    document.getElementById("i1").addEventListener('click',(e) => {
        alert(1);
    },true) 
    document.getElementById("i2").addEventListener('click',(e) => {
        alert(2);
    })  
    document.getElementById("i3").addEventListener('click',(e) => {
        alert(3);
    })     
</script>
</html>

document對象與i1節點綁定的是捕獲型的監聽事件,i2i3節點綁定的是冒泡型的事件,事件傳遞的順序為:

window --- document --- html --- body --- i1 --- i2 --- i3 --- i2 --- i1 --- body --- html --- document --- window

windowi3的過程為捕獲階段,依次執行了過程中綁定的事件,本例中執行了alert(0)alert(1),然后到達目標階段i3,執行i3綁定的事件alert(3),然后從i3window的階段為冒泡階段,執行了綁定的alert(2),執行順序即為0 1 3 2

注意

綁定監聽事件使用的區別

DOM0中直接綁定函數執行時,后定義的函數會覆蓋前邊綁定的函數,下面這個例子只執行alert(1)而不執行alert(0)click()是一個對象事件,點擊即觸發onclick()綁定的方法,onclick()是對象的屬性,將其綁定函數后即為click()事件觸發后執行的方法。

<!DOCTYPE html>
<html>
<head>
    <title>JS事件流模型</title>
</head>
<style type="text/css">
    div{
        display: flex;
        justify-content: center;
        align-items: center;
    }
</style>

<body>
    <div id="i1" style="height: 150px;width: 150px;background: red;"></div>
</body>

<script type="text/javascript">

    document.getElementById("i1").onclick = function(){
        alert(0);
    } // 被覆蓋

    document.getElementById("i1").onclick = function(){
        alert(1);
    } // 執行
    
</script>
</html>


addEventListener可以為事件綁定多個函數,並且綁定時不需要加on,其還可以接收第三個參數useCapture來決定事件時綁定的捕獲階段還是冒泡階段執行。

    document.getElementById("i1").addEventListener('click',(e) => {
        alert(0);
    }) // 執行

    document.getElementById("i1").addEventListener('click',(e) => {
        alert(1);
    }) // 執行

attachEvent可以為事件綁定多個函數,綁定時需要加on,其只支持冒泡階段執行,所以不存在第三個參數。

    document.getElementById("i1").attachEvent('onclick',function(e){
        alert(0);
    }) // 執行

    document.getElementById("i1").attachEvent('onclick',function(e){
        alert(1);
    }) // 執行

每日一題

https://github.com/WindrunnerMax/EveryDay


免責聲明!

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



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