一片文章讀懂DOM事件模型

DOM事件模型

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

DOM事件流

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

  1. 事件捕獲階段
  2. 處于目標階段
  3. 事件冒泡階段
DOM事件流

可以通過addEventListener注冊事件時聲明捕獲還是冒泡階段,處于捕獲階段的事件會比冒泡階段先發(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. 注冊事件監(jiān)聽器
    2. 常用格式target.addEventListener(type, listener, useCapture)
    3. 回調(diào)listener的第一個參數(shù)可以是event對象
    4. useCapture表示注冊的是捕獲階段(true)還是冒泡階段(false,默認)
  4. stopPropagation,阻止事件傳遞
  5. preventDefault,阻止事件默認行為,下面兩個例子
    1. 阻止復(fù)選框被勾選
    2. 阻止input寫入內(nèi)容

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

重點解析

bubbles

默認為false,當為false時不發(fā)生事件冒泡,也就是說,如果注冊的事件監(jiān)聽器是冒泡階段捕獲的話,將不會發(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不會發(fā)生,因為事件demoEvent的bubbles是false,事件沒有冒泡階段

cancelable

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

自定義事件

邏輯如下:

  1. 新建一個事件對象,Event或者CustomEvent都行,但是變量名不要取event,因為在回調(diào)里會因為作用域問題被屏蔽
  2. 用一個節(jié)點對象發(fā)起事件(dispatch),該節(jié)點就算是事件流里的目標對象
  3. 在事件流里的所有注冊了該事件的節(jié)點對象,都會調(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)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

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

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