1. EventTarget
1.1 EventTarget物件
事件物件是事件的基礎,事件都不是獨立存在的,需要繫結在一個事件物件上,監聽物件的變化,當物件發生相關事件變化時觸發對應回撥。
window, document, Element都是EventTarget物件,一些非節點元素也是EventTarget,比如Ajax中的XMLHttpRequest物件
1.2 EventTarget物件方法
1.2.1 addEventListener
利用addEventListener
可以給EventTarget
增加Event
事件,方法接受最多三個引數:
addEventListener(type, listener[, options/capture])
type
: 事件型別,可以是瀏覽器支援的DomEvent
,也可以是自己自定義的CustomEvent
listener
: EventListener
,UserAgent
將事件傳送給EventListener
的時候,會觸發listener
物件中的handleEvent
方法。由於歷史遺留,通常我們寫EventListener
的時候第二個引數都是一個方法
eventTarget.addEventListener('click', ev => {})
複製程式碼
實際上等價於
eventTarget.addEventListener('click', {handleEvent: ev => {}})
複製程式碼
options/caputure
: 第三個引數為可選,接受一個Object
/Boolean
,接受Object
可以指定三個屬性:capture
, once
, passive
capture: 設定事件捕獲方式,預設為
false
,不使用捕獲,事件使用冒泡機制;設定為true
,使用捕獲機制
once: 事件是否只觸發一次
passive:EventListener
內部是否可以使用event.preventDefault()
,設定為true的時候將不能使用,否則會提示錯誤資訊:Unable to preventDefault inside passive event listener invocation.
簡明一下瀏覽兩種事件觸發機制:冒泡和捕獲,冒泡是從內向外,捕獲是從外向內,借用網上經典的一個圖示來說明:
PS:
- 老版本的
IE
瀏覽器使用attachEvent
來作為addEventListener
的替代方法 - 同一個事件多次繫結相同的函式並不會多次觸發 例如:
document.addEventListener('click', () => {console.log('click')})
document.addEventListener('click', () => {console.log('click')})
複製程式碼
這樣進行繫結,當點選頁面的時候會觸發兩次,但是如果按照以下方式進行繫結,則只會觸發一次
function click() {
console.log('click')
}
document.addEventListener('click', click)
document.addEventListener('click', click)
複製程式碼
1.2.2 removeEventListener
移除繫結的EventListener
物件
removeEventListener(type, listener[, useCapture])
同樣支援三個引數,第一個引數type
為移除的事件型別,第二個引數為EventListener
物件,必須和addEventListener
新增的物件是同一個物件/方法,第三個引數為移除冒泡還是移除捕獲的事件
1.2.3 dispathEventListener
通常我們通過增加部分已經被定義的EventListener
事件型別,例如:click
, input
等,直到使用者發生互動行為或EventTarget
物件操作結束,觸發繫結的事件;除此以外,其實可以自定義EventTarget
以及CustomEvent
,並且利用dispatchEvent
在任意時候手動觸發相關事件,例如:
let eventTarget = new EventTarget();
let event = new CustomEvent('myEvent', {detail: 'test' });
eventTarget.addEventListener('myEvent', () => {
console.log('trigger event')
})
eventTarget.dispatchEvent(event);
複製程式碼
2. Events
2.1 Event
Event
是所有Event
物件的基類,包含了一些基礎的屬性
2.1.1 只讀屬性
bubbles
: 判斷事件是否冒泡
cancelable
: 判斷事件是否可以取消
composed
: 判斷事件是否可以從ShadowDom
傳遞到ShadowDom
currentTarget
: 事件註冊的物件
defaultPrevented
: 判斷事件是否執行了preventDefault()
eventPhase
: 獲得事件觸發階段(0: Event.NONE
, 1: Event.CAPTURE_PHASE
捕獲階段, 2: Event.AT_TARGET
到達觸發目標階段, 3: Event.BUBBLING_PHASE
冒泡階段)
target
:事件傳送的原始目標,和currentTarget
區別在於,currentTarget
是事件註冊的目標(有可能是target
的父節點)
type
: 觸發事件型別
timeStamp
: 事件從建立成功後到觸發時所用的時間,單位毫秒
isTrusted
: 判斷事件是使用者觸發還是非使用者觸發,true
代表使用者觸發的事件
2.1.2 讀寫屬性
cancelBubble
: Event.stopPropagation()
歷史別名,設定為true
以後會阻止事件冒泡
returnValue
: 已經被preventDefault()
替代,設定為false
以後會阻止預設的事件
srcElement
: IE
舊版本瀏覽器中的target
物件
2.1.3 方法
composedPath()
: 獲取觸發事件路徑,會返回從target
到Window
的事件路徑陣列
preventDefault()
: 阻止預設的事件,例如input
的預設事件是輸入,如果keyup/keydown
事件使用了preventDefault()
,則輸入框將無法輸入字元
stopImmediatePropagation()
: 阻止其他type
相同的事件的觸發,也就是同一個EventTarget
的相同type
事件只會觸發一個
stopPropagation()
:阻止事件的冒泡/捕獲
2.2 事件列舉(不完全列舉)
大部分的type
事件有特定事件型別,不同的瀏覽器對具體事件型別支援的程度不一而同,列舉一些常用的事件子類,及會得到該子類的type
型別
2.2.1 FocusEvent
blur
: 失去焦點,不會冒泡
focusout
: 失去焦點,支援冒泡
focus
: 獲得焦點,不會冒泡
focusin
: 獲得焦點,支援冒泡
2.2.2 MouseEvent
mouseenter
: 滑鼠移入元素
mouseleave
: 滑鼠移出元素
mouseover
: 滑鼠移入元素/子元素(給父元素繫結以後,從父元素到子元素,或者從子元素到父元素都會觸發)
mouseout
: 滑鼠移出元素/子元素
mousemove
: 滑鼠在元素上持續移動
mousedown
: 滑鼠在元素上點選
mouseup
: 滑鼠在元素上釋放點選
click
: 滑鼠點選(按下和釋放必須同時觸發),支援冒泡
dbclick
: 滑鼠雙擊
contextmenu
: 滑鼠右鍵開啟選單欄(監聽該事件後可以使用event.preventDefault()阻止開啟右鍵選單)
wheel
: 滑鼠滾輪的滾動
2.2.3 CompositionEvent
有隻讀的data
屬性,event.data
可以獲取到正在輸入到字串
compositionend
: 段落文字組成完成,比如:輸入法元件關閉
compositionstart
: 文字輸入前觸發,不同於keydown
,在輸入法控制元件開啟時候觸發(據說也支援語音識別開啟)
compositionupdate
: 輸入法開啟後,文字輸入過程觸發
2.2.4 ErrorEvent
error
: 資源載入失敗,頁面throw Error()
可以進行捕獲
2.2.5 InputEvent
input
: 對於<input type="text">, <textarea>, <select>
元素值發生更改時同步觸發,對於<input type="radio">, <input type="checkbox">
的元素,每次切換控制元件時觸發,contenteditable=true
內的內容變更也會觸發
change
: 不同於input
,不一定每一次變化都會觸發,焦點遺失/會車等操作會觸發
2.2.6 KeyboardEvent
keydown
: 鍵盤按鍵按下,無論是否產生字元都會觸發
keypress
: 鍵盤按鍵按下,產生字元時觸發,因此ctrl
,shift
不產生字元都鍵位不會觸發
keyup
: 鍵盤按鍵釋放
2.2.7 AnimationEvent
animationstart
: CSS動畫開始
animationedn
: CSS動畫結束
animationiteration
: CSS動畫重複開始時觸發
2.2.8 TransitionEvent
*transtionstart
: CSS中transition
實際發生時,會在transition-delay
後觸發,實驗性質事件
transitionend
: CSS的transition
結束的時候觸發
*transitionrun
: transition-delay
前觸發,實驗性質事件
2.2.9 ClipboardEvent
cut
: 發生剪下時觸發,包括鍵盤快捷鍵和選單欄中的操作
copy
: 發生複製時觸發,包括鍵盤快捷鍵和選單欄操作和document.execCommand('copy')
,可以通過event.preventDefault()
阻止複製,可以通過event.clipboardData.setData()
和getData()
來獲取內容
paste
: 發生貼上時觸發
2.2.10 TouchEvent
主要是使用在觸屏上的監聽
touchcancel
: 一個或者多個觸點觸碰時,草畜了觸點支援的數量而被取消時觸發
touchend
: 一個或多個觸點觸碰結束時觸發
touchemove
: 一個或多個觸點移動的時候觸發
touchstart
: 一個或多個觸點開始觸碰時觸發
2.2.11 PointerEvent
由於螢幕裝置的擴充套件,所以操作手段不在侷限於滑鼠,所以提供了一套和滑鼠操作相同的API,來支援類似的觸控事件
pointerover
: 和mouseover
等同
pointerenter
: 和mouseenter
等同
pointerdown
: 和mousedown
等同
pointermove
: 和mousemove
等同
pointerup
: 和mouseup
等同
pointerout
: 和mouseout
等同
pointerleave
: 和mouseleave
等同
2.2.12 DragEvent
拖動相關事件,其實分為了拖動元素事件和釋放區域事件兩類
拖動元素事件:
dragstart
: 元素開始拖動
drag
: 元素拖動中(每350ms觸發一次)
dragend
: 元素拖動結束
釋放區域事件
dragenter
: 拖動進入了drop目標區域,進入子節點也會反覆觸發
dragover
: 元素在drop目標區域中移動(每350ms觸發一次),需要設定event.preventDefault()
元素才能在該區域drop
dragleave
: 拖動離開了drop目標區域,進入子節點也會觸發
drop
: 元素在drop目標區域中拖動被釋放
2.2.13 MediaEvent
媒體播放相關事件,針對H5視訊<video>
和音訊<audio>
播放器的事件
durationchange
: duration屬性更新
loadedmetadata
: metadata屬性載入
loadeddata
: media完成載入
canplay
: 可以播放media的時候觸發(拖動進度條會觸發)
canplaythrough
: 可以播放整個media時觸發(拖動進度條會觸發)
ended
: media播放結束觸發
stalled
: 請求media資料,但是劇沒有如預期到來時觸發
suspend
: media請求掛起時觸發
play
: media播放開始
playing
: media播放中
pause
: media暫停
waiting
: 缺少資料載入
seeking
: 時間進度條操作變動
seeked
: 時間進度條操作變動停止
ratechannge
: 播放速率改變
timeupdate
: currentTime屬性更新(播放過程中時間變動)
volumechange
: 音量調節
2.2.14 其他
select
: 文字選中,只能監聽input
和textarea
的選中(該事件和document.execCommand('copy')
可以實現點選複製功能)
DOMContentLoaded
: DOM
載入完成,不會等待樣式,圖片渲染,Chrome中的devtool中Network中可以看到相關載入時間應該就是使用該監聽來處理的
beforeunload
: 離開頁面前觸發,設定event.returnValue=true
,將彈出提示訊息來確認是否關閉
offline/online
: 在瀏覽器丟失網路/獲得網路時觸發
beforeprint
: 準備列印/開啟列印預覽時觸發
afterprint
: 開始列印/關閉列印預覽後時觸發
reset/submit
: 表單重置/提交按鈕點選時觸發
fullscreenchange/resize/scroll
:瀏覽器全屏/尺寸修改/滾動時觸發
hashChange
: URL中#以及#後面的值發生變化的時候觸發,可能前端框架的路由機制可以用該監聽實現
readstatechange
: document
的readyState
發生變化的時候觸發,可以作為DomContentLoaded
的替代
invalid
: h5表單提交,繫結元素不符合規則的時候觸發(input元素可以設定驗證規則屬性,例如:required
, max
, min
, pattern
,可以通過偽類:invalid
獲取到資料)
message
: WebWorks資訊接受時觸發
2.3 CustomEvent
在 1.2.3 dispathEventListener 中提到了CustomEvent
,可以根據自己的需求定義事件,並通過dispatchEvent
來觸發繫結的自定義事件