一片文章讀懂DOM事件模型

DOM事件模型

  1. 從技術(shù)上來說,W3C的DOM標(biāo)準(zhǔn)并不支持上述最原始的添加事件監(jiān)聽函數(shù)的方式,這些都是在DOM標(biāo)準(zhǔn)形成前的事件模型。盡管沒有正式的W3C標(biāo)準(zhǔn),但這種事件模型仍然得到廣泛應(yīng)用,這就是我們通常所說的0級(jí)DOM。
<input type="button" id="myButton" onclick="alert('Button Click')" />   
或
document.getElementById("myButton").onclick = function () {  
    alert("Button Click");  
}   
  1. 沒有1級(jí)DOM。DOM級(jí)別1于1998年10月1日成為W3C推薦標(biāo)準(zhǔn)。1級(jí)DOM標(biāo)準(zhǔn)中并沒有定義事件相關(guān)的內(nèi)容,所以沒有所謂的1級(jí)DOM事件模型。
  2. 在2級(jí)DOM中除了定義了一些DOM相關(guān)的操作之外還定義了一個(gè)事件模型 ,這個(gè)標(biāo)準(zhǔn)下的事件模型就是我們所說的2級(jí)DOM事件模型。
document.getElementById("myButton").addEventListener("click",
        function (event) {
            alert("Button Click");
            console.log(event)
        },
        true)
        // 回調(diào)的第一個(gè)參數(shù)是被觸發(fā)的事件對(duì)象,下面會(huì)簡(jiǎn)單介紹Event

DOM事件流

描述的就是從頁面中接受事件的順序。分有事件冒泡與事件捕獲兩種。
DOM事件流有三個(gè)階段:

  1. 事件捕獲階段
  2. 處于目標(biāo)階段
  3. 事件冒泡階段
DOM事件流

可以通過addEventListener注冊(cè)事件時(shí)聲明捕獲還是冒泡階段,處于捕獲階段的事件會(huì)比冒泡階段先發(fā)生

相關(guān)API

  1. Event(typeArg, eventInit)
    1. type
    2. target
    3. currentTarget
    4. clientX, clientY
    5. screenX, screenY
  2. CustomEvent(typeArg, eventInitDict)
  3. addEventListener
    1. 注冊(cè)事件監(jiān)聽器
    2. 常用格式target.addEventListener(type, listener, useCapture)
    3. 回調(diào)listener的第一個(gè)參數(shù)可以是event對(duì)象
    4. useCapture表示注冊(cè)的是捕獲階段(true)還是冒泡階段(false,默認(rèn))
  4. stopPropagation,阻止事件傳遞
  5. preventDefault,阻止事件默認(rèn)行為,下面兩個(gè)例子
    1. 阻止復(fù)選框被勾選
    2. 阻止input寫入內(nèi)容

簡(jiǎn)單說一下,Event的eventInit和CustomEvent的eventInitDict的區(qū)別
Event的eventInit有三個(gè)屬性可以選擇:bubbles表示是否可以冒泡,cancelable表示是否可以被取消,還有一個(gè)不常用的composed;
CustomEvent的eventInitDict,除了上面的bubbles和cancelable,還有一個(gè)details,它可以傳入你自定義的一些數(shù)據(jù),供給注冊(cè)事件監(jiān)聽器時(shí)在回調(diào)里面可以調(diào)用的一些數(shù)據(jù)

重點(diǎn)解析

bubbles

默認(rèn)為false,當(dāng)為false時(shí)不發(fā)生事件冒泡,也就是說,如果注冊(cè)的事件監(jiān)聽器是冒泡階段捕獲的話,將不會(huì)發(fā)生

var button = document.getElementById('clickMe');

    var myEvent = new CustomEvent('demoEvent', {
        bubbles: false,
        cancelable: false,
        detail: {
            index: 'hello demo'
        }
    })

    button.addEventListener('click', function () {
        console.log('1. You click Button')
        button.dispatchEvent(myEvent)
    }, true);

    document.body.addEventListener('demoEvent', function () {
        console.log('2. You click body')
    }, false);

    document.addEventListener('demoEvent', function (e) {
        console.log('3. You click document')
    }, true);

    window.addEventListener('demoEvent', function (e) {
        console.log('4. You click window')
    }, false);

上面的2和3不會(huì)發(fā)生,因?yàn)槭录emoEvent的bubbles是false,事件沒有冒泡階段

cancelable

如果該事件的 cancelable 屬性為 false, 則該事件的監(jiān)聽器無法阻止默認(rèn)行為, 調(diào)用preventDefault() 將產(chǎn)生錯(cuò)誤

自定義事件

邏輯如下:

  1. 新建一個(gè)事件對(duì)象,Event或者CustomEvent都行,但是變量名不要取event,因?yàn)樵诨卣{(diào)里會(huì)因?yàn)樽饔糜騿栴}被屏蔽
  2. 用一個(gè)節(jié)點(diǎn)對(duì)象發(fā)起事件(dispatch),該節(jié)點(diǎn)就算是事件流里的目標(biāo)對(duì)象
  3. 在事件流里的所有注冊(cè)了該事件的節(jié)點(diǎn)對(duì)象,都會(huì)調(diào)用回調(diào)
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Event Bubbling</title>
</head>

<body>
    <button id="clickMe">Click Me</button>
</body>

</html>
<script>
    var button = document.getElementById('clickMe');

    var myEvent = new CustomEvent('demoEvent', {
        bubbles: true,
        cancelable: false,
        detail: {
            index: 'hello demo'
        }
    })

    button.addEventListener('click', function () {
        console.log('1. You click Button')
        button.dispatchEvent(myEvent)
    }, true);

    document.body.addEventListener('demoEvent', function () {
        console.log('2. You click body')
    }, false);

    document.addEventListener('demoEvent', function (e) {
        console.log('3. You click document')
    }, true);

    window.addEventListener('demoEvent', function (e) {
        console.log('4. You click window')
    }, false);
</script>

參考

這篇博客是參考了很多博客和API文檔,總結(jié)出來的。
包括但不限于:
事件模型淺析
Event
CustomEvent
創(chuàng)建和觸發(fā) events

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • ??JavaScript 與 HTML 之間的交互是通過事件實(shí)現(xiàn)的。 ??事件,就是文檔或?yàn)g覽器窗口中發(fā)生的一些特...
    霜天曉閱讀 3,669評(píng)論 1 11
  • 事件是一種異步編程的實(shí)現(xiàn)方式,本質(zhì)上是程序各個(gè)組成部分之間的通信。DOM支持大量的事件,本節(jié)介紹DOM的事件編程。...
    許先生__閱讀 1,023評(píng)論 0 3
  • Dom事件 事件是一種異步編程的實(shí)現(xiàn)方式,本質(zhì)上是程序各個(gè)組成部分之間的通信。DOM支持大量的事件 (一) Eve...
    woow_wu7閱讀 1,888評(píng)論 0 1
  • js之事件機(jī)制 1、事件初探 1.1 js事件的概述 JavaScript事件:JavaScript是基于事件驅(qū)動(dòng)...
    道無虛閱讀 2,630評(píng)論 0 2
  • 我是一名勁椎病患者,這不奇怪,畢竟很多人都會(huì)。 我的勁椎病大多是壓迫到神經(jīng),這回讓我頻繁的做噩夢(mèng),做很壓抑的夢(mèng)。 ...
    lichun閱讀 206評(píng)論 0 0

友情鏈接更多精彩內(nèi)容