Javasript學習筆記-Event事件

在前端開發過程當中,頁面交互過程和事件機制密不可分,一直以來對於事件相關機制瞭解的不夠深入,沒有好好進行了解,最近花了一點時間,梳理了一下事件機制以及相關經常使用的事件。

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])bash

type: 事件類型,能夠是瀏覽器支持的DomEvent,也能夠是本身自定義的CustomEvent前端框架

listener: EventListenerUserAgent將事件發送給EventListener的時候,會觸發listener對象中的handleEvent方法。因爲歷史遺留,一般咱們寫EventListener的時候第二個參數都是一個方法網絡

eventTarget.addEventListener('click', ev => {})
複製代碼

實際上等價於框架

eventTarget.addEventListener('click', {handleEvent: ev => {}})
複製代碼

options/caputure: 第三個參數爲可選,接受一個Object/Boolean,接受Object能夠指定三個屬性:capture, once, passiveide

capture: 設置事件捕獲方式,默認爲false,不使用捕獲,事件使用冒泡機制;設置爲true,使用捕獲機制
once: 事件是否只觸發一次
passive: EventListener內部是否可使用event.preventDefault(),設置爲true的時候將不能使用,不然會提示錯誤信息: Unable to preventDefault inside passive event listener invocation.函數

簡明一下瀏覽兩種事件觸發機制:冒泡和捕獲,冒泡是從內向外,捕獲是從外向內,借用網上經典的一個圖示來講明:動畫

PS:

  1. 老版本的IE瀏覽器使用attachEvent來做爲addEventListener的替代方法
  2. 同一個事件屢次綁定相同的函數並不會屢次觸發 例如:
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(): 獲取觸發事件路徑,會返回從targetWindow的事件路徑數組

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: 文本選中,只能監聽inputtextarea的選中(該事件和document.execCommand('copy')能夠實現點擊複製功能)

DOMContentLoaded: DOM加載完成,不會等待樣式,圖片渲染,Chrome中的devtool中Network中能夠看到相關加載時間應該就是使用該監聽來處理的

beforeunload: 離開頁面前觸發,設置event.returnValue=true,將彈出提示消息來確認是否關閉

offline/online: 在瀏覽器丟失網絡/得到網絡時觸發

beforeprint: 準備打印/打開打印預覽時觸發

afterprint: 開始打印/關閉打印預覽後時觸發

reset/submit: 表單重置/提交按鈕點擊時觸發

fullscreenchange/resize/scroll:瀏覽器全屏/尺寸修改/滾動時觸發

hashChange: URL中#以及#後面的值發生變化的時候觸發,可能前端框架的路由機制能夠用該監聽實現

readstatechange: documentreadyState發生變化的時候觸發,能夠做爲DomContentLoaded的替代

invalid: h5表單提交,綁定元素不符合規則的時候觸發(input元素能夠設置驗證規則屬性,例如:required, max, min, pattern,能夠經過僞類:invalid獲取到數據)

message: WebWorks信息接受時觸發

2.3 CustomEvent

1.2.3 dispathEventListener 中提到了CustomEvent,能夠根據本身的需求定義事件,並經過dispatchEvent來觸發綁定的自定義事件

3. 參考

MDN Event reference

相關文章
相關標籤/搜索