Javascript高級編程學習筆記(71)—— 模擬事件(1)DOM事件模擬
事件,指的是網頁中某個特定的交互時刻
一般來說事件由瀏覽器廠商負責提供,一般由用戶操作或者其它瀏覽器功能來觸發
但是有一類特殊的事件,那就是由我們開發人員通過JS觸發的事件
這些事件和瀏覽器創建的事件一樣,都可以冒泡,並且在其觸發時運行事先指定給它的事件處理程序
在測試web程序的過程中這種模擬觸發事件是一種極其有用的技術,為此DOM2級規範將其納入規範
規範化了模擬事件的方式,這種DOM規範規定的模擬事件的技術手段也叫做DOM事件模擬
PS:模擬事件和自定義事件是有區別的,模擬事件指的是我們並不去真的觸發瀏覽器中的事件,而是用代碼去觸發事件來模擬事件發生的情況。 而自定義事件不過是模擬事件中的一種罷了
DOM事件模擬
首先我們知道事件處理程序和一般的函數的區別就在於,事件處理程序的函數在事件觸發時會傳入一個 event 事件對象
那麽要模擬事件首先就需要創建 event 事件對象
創建事件對象我們可以調用 document 上的 createEvent()方法創建 event 事件對象
該方法接收一個參數,用於表示要創建的事件的類型
在DOM2級規範中這些字符串都使用英文復數形式,而在DOM3中這些字符串都變成了單數形式
以DOM2級規範為例,該函數的參數可以是以下幾個字符串之一:
- UIEvents:一般的UI事件,鼠標事件和鍵盤事件都繼承自UI事件
- MouseEvents:一般的鼠標事件
- MutationEvents:一般的DOM變動事件
- HTMLEvents:一般的HTML事件(DOM3中沒有對應的值,DOM3中HTML事件被拆分到了其它類別中)
在創建了 event 對象之後,還需使用與事件有關的信息才能對其進行初始化,對於不同類型的 event 對象有不同的方法來對其進行初始化(取決於createEvent()方法傳入的參數)
初始化完成後,我們就只需要在代碼中我們希望的位置觸發即可
觸發時我們需要在DOM元素上調用 dispatchEvent()方法(該方法得到所有能夠觸發事件的元素支持),此時需要傳入我們之前創建的 event 對象作為該方法的參數
這樣我們模擬的事件就像官方的事件那樣能夠冒泡,並且觸發相應的事件處理程序了
模擬鼠標事件
創建新的鼠標事件並為其指定必要信息就可以模擬鼠標事件
這裏需要詳細講的是初始化事件對象
我們在得到 createEvent 方法創建的 MouseEvent 事件對象後,該對象上有一個方法:
initMouseEvent()
該方法接收15個參數以此對應正常的瀏覽器事件中的鼠標事件的事件對象:
- type(字符串):表示觸發鼠標事件的具體類型,如“click”
- bubbles(布爾值):表示該事件是否冒泡,為準確模擬鼠標事件應該為 true
- cancelable(布爾值):表示該事件是否可以取消,為準確模擬應為 true
- view(AbstractView):與事件關聯的視圖,應該設置為 document.defaultView
- detail(整數):與事件有關的詳細信息,此處應該設為0
- screenX(整數):相對於屏幕的X坐標
- screenY(整數):相對於屏幕的Y坐標
- clientX(整數):相對於視口的X坐標
- clientY(整數):相對於視口的Y坐標
- ctrlKey(布爾值):表示是否按下ctrl,默認false
- altKey(布爾值):表示是否按下alt,默認false
- shiftKey(布爾值):表示是否按下shift鍵,默認false
- metaKey(布爾值):表示是否按下meta鍵,默認false
- button(整數):表示按下哪一個鼠標鍵
- relatedTarget(元素):表示與當前事件關聯的元素對象,該參數只在模擬mouseover或mouseout時使用
由於是在希望觸發的元素上調用 dispatchEvent(),所以 tartget 屬性會自動傳入
代碼如下:
var btn = document.getElementById(‘myButton‘); //創建事件對象 var event = document.createEvent(‘MouseEvents‘);//DOM3不用s //初始化事件對象 event.initMouseEvent("click",true,true,document.defaultView,0,0,0,0,false,false,false,false,0,null); //觸發事件 btn,dispatchEvent(event);
這樣就完成了一個鼠標事件的模擬
模擬鍵盤事件
鍵盤事件在DOM3中正式納入規範,所以這裏只介紹DOM3中的模擬鍵盤事件
與模擬鼠標事件的區別在於
- 傳入的事件類型字符串為:KeyboardEvent
- 事件包含的初始化方法為:initKeyEvent
initKeyEvent接收的參數如下:
- type(字符串):表示要觸發的事件類型,如“keydown”
- bubbles(布爾值):表示事件是否應該冒泡,準確模擬應該為 true
- cancelable(布爾值):表示事件是否可以取消,準確模擬應為 true
- view(AbstractView):一般來說為 document.defaultView
- key(字符串):按下鍵的鍵碼
- location(整數):表示按下了哪裏的鍵,0默認主鍵盤,1左,2右,3數字鍵盤,4移動設備,5手柄
- modifiers(字符串):空格分隔的修改鍵列表如”Shift Ctrl“
- repeat(整數):在一行中按了這個鍵多少次
var event = document.createEvent(‘KeyboardEvent‘); //初始化事件對象 event.initKeyboardEvent(‘keydown‘,true,true,document.defaultView,"a",0,"Shit ",0); //觸發事件 btn.dispatchEvent(event);
要註意的是火狐中模擬鍵盤事件和標準DOM中有所不同
- 事件類型參數:”KeyEvents“
- 初始化方法:initKeyEvent()
- 初始化方法的參數:從第五個開始不同
- ctrlKey:表示是否按下 ctrl鍵
- altKey:表示是否按下alt鍵
- shiftKey:表示是否按下shift
- metaKey:表示是否按下meta
- keyCode(整數):被按下鍵的鍵碼
- charCode(整數):通過按鍵生成字符的ASCLL碼
模擬變動事件
初始化參數為:
- type
- bubbles
- cancelable
- relatedNode:關聯的DOM節點
- preValue:變動前的值
- newValue:變動後的值
- attrName:特姓名
- attrChange:特性變動
示例如下:
var event = document.createEvent("MutationEvents"); event.initMutationEvent("DOMNodeInserted",true,false,someNode,"","","",0); target.dispatchEvent(event);
模擬HTML事件
以focus事件為例:
var event =document.createElement(‘HTMLEvents‘); event.initEvent("focus",true,false); target.dispatchEvent(event);
自定義事件
除了向上面那樣模擬瀏覽器事件之外,我們也可以創建自己的自定義事件
與瀏覽器事件的區別在於,初始化事件不同
自定義事件的初始化方法為:initCustomEvent
接收以下參數:
- type:觸發事件的類型
- bubbles:是否冒泡
- cancelable:是否可以取消
- detail(對象):可以是任意值
示例如下:
var event = document.createEvent("CustomEvent"); event.initCustomEvent("myEvent",true,false,"hello"); target.dispatchEvent(event);
像上面這樣冒泡的自定義事件是可以其它元素指定針對該自定義事件的事件處理程序的
如:
document.addEventListener("myEvent",function(event){ console.log(event.detail); },false);
Javascript高級編程學習筆記(71)—— 模擬事件(1)DOM事件模擬