五分鐘瞭解DOM 事件模型

通俗理解,事件是用戶或者瀏覽器本身執行的某種動做,是文檔或者瀏覽器發生的一些交互瞬間,好比點擊(click)按鈕等,這裏的click就是事件的名稱。JS與html之間的交互是經過事件實現的,DOM支持大量的事件。DOM 事件模型這個知識點,在面試的時候也是常考知識~html

事件流

咱們知道,DOM是個樹形結構,當咱們在頁面上單擊一個按鈕,頁面上哪些元素會觸發這個事件,是發生在這個按鈕上,仍是這個按鈕的容器元素(咱們說父元素)也會觸發這個點擊事件呢? 這就牽扯到事件流,從上面的思考,咱們知道它描述的是事件觸發順序,那上文中是按鈕和其容器元素都觸發嗎,它們誰先觸發呢?這可不是肯定的,得看是哪一種類型的事件流了。面試

一、事件冒泡

事件冒泡是IE 的事件流,事件是由最具體的元素接收,而後逐級向上傳播,在每一級的節點上都會發生,直到傳播到document對象,向Chrome這樣的瀏覽器會冒泡到window 對象(很容易記憶,聯想水裏的泡泡不也這樣麼)。瀏覽器

二、事件捕獲

事件捕獲是Netscape瀏覽器開發團隊提出的,頗有意思,他們思想和IE 的截然相反。也就是說,從不具體的節點到最具體的節點,通常是從document對象開始傳播,不過不多人用事件捕獲的,仍是事件冒泡用的多。bash

三、DOM 事件流

這裏規定的事件流有三個階段: 事件捕獲階段,目標階段,事件冒泡階段。函數

事件處理程序

前面簡單說了什麼是事件,那響應事件的函數就是事件處理程序。好比click是事件名稱,加上"on"開頭,事件處理程序是onclick,有如下幾種方式來給事件指定事件處理程序。ui

一、HTML 事件處理程序

其實就是,HTML 的on屬性。spa

<button onclick="doSomething()">點擊</button>
複製代碼

⚠️ on + 事件名,由於要執行函數,我這裏寫的doSomething(),這是會執行的代碼,不能寫個函數名哈,要記得帶上括號。使用這個方法指定的監聽代碼,只會在冒泡階段觸發。code

二、DOM0 級事件處理程序

其實就是,元素節點的事件屬性。htm

var btn = document.getElementById('btn');
btn.onclick = function () {
  console.log('被點擊了!');
};
複製代碼

⚠️ 這樣就獲取按鈕的引用,並給它指定事件onclick,點擊後在控制檯輸出'被點擊了!'。
若是想刪除事件處理程序,只須要這樣 btn.onclick = null; // 刪除事件處理程序對象

三、DOM2 級事件處理程序

記住2個方法,addEventListener()removeEventListener(),用於添加和刪除事件處理程序。

(1)EventTarget.addEventListener()

target.addEventListener(eventType, listener[, useCapture]);
複製代碼

eventType ————> 事件名稱,大小寫敏感
listener ————> 監聽函數
useCapture ————> 可選參數,默認false,表示監聽函數只在冒泡階段被觸發。
舉個例子:

function print() {
  console.log('Print Hello world');
}

var btn = document.getElementById('btn');
btn.addEventListener('click', print, false);

複製代碼

上面代碼的意思就是,節點id爲btn的元素,使用addEventListener方法綁定click事件,點擊的時候會監聽函數print會發生。另外,由於useCapture設置爲false,因此該函數只在冒泡階段觸發。
當咱們須要添加多個不一樣的監聽函數,使用addEventListener很是棒,聽從先添加先觸發原則,並且不當心在同一個事件重複添加了同一個函數,它還會自動移除,該函數只會執行一次。

(2)EventTarget.removeEventListener()
顧名思義,用來移除addEventListener方法添加的事件監聽函數。
它的參數和addEventListener方法一致,並且寫的時候要一一對應。要作到三同,一是在同一個元素節點,二是同一個監聽函數,三是第三個參數要一致。

四、IE 事件處理程序

(1)事件綁定監聽函數:attachEvent(eventType, listener)
(2)事件移除監聽函數:detachEvent(eventType, listener)

事件對象

一、DOM 中事件對象

事件發生的時候,會將一個 event 對象傳入到事件處理程序中,從而可使用對象的屬性和方法。我隨意列出幾個。
bubbles:返回一個布爾值,表示當前事件是否會冒泡。該屬性爲只讀屬性
cancelable:返回一個布爾值,表示事件是否能夠取消。該屬性爲只讀屬性
currentTarget:事件處理程序當前正在處理事件的那個元素
preventDefault():取消事件的默認行爲。若是 cancelable 是true,則可使用這個方法
stopPropagation():取消事件的進一步捕獲或冒泡。若是 bubbles爲 true,則可使用這個方法。
事件處理程序使用DOM0 級或是 DOM2 級,都會傳入 event 對象,這個咱們不用care。

var btn = document.getElementById("myBtn");
btn.onclick = function(event){
      console.log(event.type);    //"click"
  };
btn.addEventListener("click", function(event){
      console.log(event.type);    //"click"
  }, false);
<button onclick="console.log(event.type)()">點擊</button>
複製代碼

二、IE 中事件對象

根據事件處理程序,有不一樣的方式。 (1) HTML 事件處理程序

<button onclick="console.log(event.type)()">點擊</button>
複製代碼

(2) DOM0 級事件處理程序

var btn = document.getElementById("btn");
btn.onclick = function(){
 var event = window.event;
 console.log(event.type);     //"click"
};
複製代碼

(3) DOM2 級事件處理程序

var btn = document.getElementById("btn");
btn.attachEvent("onclick", function(event){
 console.log(event.type);         //"click"
});
複製代碼
相關文章
相關標籤/搜索