事件模型
一、監聽函式
js 有三種方法,可以為事件繫結監聽函式
- HTML 的 on- 屬性
- 元素節點的事件屬性,也可以指定監聽函式
EventTarget.addEventListener()
DOM 節點例項的方法,有三個引數,分別事件型別、回撥函式和表示是否在捕獲階段觸發的布林值
上面三種方法,第一種違反了 HTML 和 JavaScript 相分離原則,不推薦。第二種方法,如果多次定義了同個屬性,後者會覆蓋前者,不推薦。
第三種方法有點:
- 同一事件可以新增多個監聽函式
- 能夠指定在哪個階段(捕獲階段還是冒泡階段)觸發監聽函式
- 除了 DOM 節點,其他物件(如
window
,XMLHttpRequest
等)也有這個介面,它等於是整個 JavaScript 統一的監聽函式介面。
二、this 指向
監聽函式內部的this
指向觸發事件的那個元素節點。
<button id="btn" onclick="console.log(this.id)">點選</button>
// btn
複製程式碼
三、事件的傳播
一個事件發生後,會在子元素和父元素之間傳播,分為三個階段:
- 第一階段:從
window
物件傳導到目標節點(上層傳到底層),稱為“捕獲階段”(capture phase) - 第二階段:在目標節點上觸發,稱為“目標階段”(target phase)
- 第三階段:從目標節點傳導回
window
物件(從底層傳回上層),稱為“冒泡階段”(bubbling phase)
四、事件代理
由於事件會在冒泡階段向上傳播到父節點,因此可以把子節點的監聽函式定義在父節點上,由父節點的監聽函式統一處理多個子元素的事件。這種方法叫做事件的代理(delegation)。
阻止事件冒泡使用event.stopPropagation
Event 物件
事件發生以後,會產生一個事件物件,作為引數傳給監聽函式。
一、例項屬性
-
Event.bubbles
返回布林值,表示當前事件是否會冒泡 -
Event.eventPhase
返回一個整數常量,表示事件目前所處階段- 0,事件目前沒有發生。
- 1,事件目前處於捕獲階段,即處於從祖先節點向目標節點的傳播過程中。
- 2,事件到達目標節點,即
Event.target
屬性指向的那個節點。 - 3,事件處於冒泡階段,即處於從目標節點向祖先節點的反向傳播過程中。
-
Event.cancelable
返回布林值,表示事件可否取消。屬性只讀 -
Event.preventDefault
當上面的值為true
時可以呼叫,用來取消事件。 -
Event.cancelBubble
屬性是一個布林值,如果設為true
,相當於執行Event.stopPropagation()
,可以阻止事件的傳播。 -
Event.currentTarget
返回事件當前所在的節點,即正在執行監聽函式所繫結的節點。Event.target
返回原始觸發事件的那個節點。 -
Event.type
返回一個表示事件型別的字串 -
Event.timeStamp
返回一個毫秒時間戳,表示事件發生的時間。 -
Event.isTrusted
返回一個布林值,表示事件是否由真實的使用者行為產生。 -
Event.detail
屬性只有瀏覽器的 UI 事件才具有,返回一個數值,表示事件的某種資訊。
二、例項方法
Event.preventDefault()
取消瀏覽器對當前事件的預設行為。Event.stopPropagation()
阻止事件冒泡Event.stopImmediatePropagetion
阻止同一個事件的其他監聽函式被呼叫,不管監聽函式定義在當前節點還是其他節點。也就是說,該方法阻止事件的傳播,比Event.stopPropagation()
更徹底。Event.composedPath()
返回一個陣列,成員是事件的最底層節點和依次冒泡經過的所有上層節點。