這就意味著會有適當?shù)氖录芭?,并且瀏覽器會執(zhí)行分配的事件處理程序。這種能力在測試 web 應(yīng)用程序的時候,是非常有用的,在 DOM 3 級規(guī)范中提供了方法來模擬特定的事件,IE9 chrome FF Opera 和 Safari 都支持這樣的方式,在 IE8 及以前的辦法的 IE 瀏覽器有他自己的方式來模擬事件
可以通過 document 上的 createEvent()方法,在任何時候創(chuàng)建事件對象,此方法只接受一個參數(shù),既要創(chuàng)建事件對象的事件字符串,在 DOM2 級規(guī)范上所有的字符串都是復(fù)數(shù)形式,在 DOM 3 級事件上所有的字符串都采用單數(shù)形式,所有的字符串如下:
UIEvents:通用的 UI 事件,鼠標事件鍵盤事件都是繼承自 UI 事件,在 DOM 3 級上使用的是 UIEvent。
MouseEvents:通用的鼠標事件,在 DOM 3 級上使用的是 MouseEvent。
MutationEvents:通用的突變事件,在 DOM 3 級上使用的是 MutationEvent。
HTMLEvents:通用的 HTML 事件,在 DOM3 級上還沒有等效的。
注意,ie9 是唯一支持 DOM3 級鍵盤事件的瀏覽器,但其他瀏覽器也提供了其他可用的方法來模擬鍵盤事件。
一旦創(chuàng)建了一個事件對象,就要初始化這個事件的相關(guān)信息,每一種類型的事件都有特定的方法來初始化,在創(chuàng)建完事件對象之后,通過 dispatchEvent()方法來將事件應(yīng)用到特定的 dom 節(jié)點上,以便其支持該事件。這個 dispatchEvent()事件,支持一個參數(shù),就是你創(chuàng)建的 event 對象。
鼠標事件可以通過創(chuàng)建一個鼠標事件對象來模擬(mouse event object),并且授予他一些相關(guān)信息,創(chuàng)建一個鼠標事件通過傳給 createEvent()方法一個字符串 "MouseEvents",來創(chuàng)建鼠標事件對象,之后通過 iniMouseEvent()方法來初始化返回的事件對象,iniMouseEvent()方法接受 15 參數(shù),參數(shù)如下:
type string 類型 :要觸發(fā)的事件類型,例如‘click'。
bubbles Boolean 類型:表示事件是否應(yīng)該冒泡,針對鼠標事件模擬,該值應(yīng)該被設(shè)置為 true。
cancelable bool 類型:表示該事件是否能夠被取消,針對鼠標事件模擬,該值應(yīng)該被設(shè)置為 true。
view 抽象視圖:事件授予的視圖,這個值幾乎全是 document.defaultView.
detail int 類型:附加的事件信息這個初始化時一般應(yīng)該默認為 0。
screenX int 類型 : 事件距離屏幕左邊的 X 坐標
screenY int 類型 : 事件距離屏幕上邊的 y 坐標
clientX int 類型 : 事件距離可視區(qū)域左邊的 X 坐標
clientY int 類型 : 事件距離可視區(qū)域上邊的 y 坐標
ctrlKey Boolean 類型 : 代表 ctrol 鍵是否被按下,默認為 false。
altKey Boolean 類型 : 代表 alt 鍵是否被按下,默認為 false。
shiftKey Boolean 類型 : 代表 shif 鍵是否被按下,默認為 false。
metaKey Boolean 類型: 代表 meta key 是否被按下,默認是 false。
button int 類型: 表示被按下的鼠標鍵,默認是零.
relatedTarget (object): 事件的關(guān)聯(lián)對象. 只有在模擬 mouseover 和 mouseout 時用到。
值得注意的是,initMouseEvent()的參數(shù)直接與 event 對象相映射,其中前四個參數(shù)是由瀏覽器用到,只有事件處理函數(shù)用到其他的參數(shù),當事件對象作為參數(shù)傳給 dispatch()方式,target 屬性將會自動被賦上值。下面是一個例子,
var btn = document.getElementById("myBtn");
var event = document.createEvent("MouseEvents");
event.initMouseEvent("click", true, true, document.defaultView, 0, 0, 0, 0, 0,false, false, false, false, 0, null);
btn.dispatchEvent(event);
在 DOM 實現(xiàn)的瀏覽器中,所有其他的事件都包括 dbclick,都可以通過相同的方式來實現(xiàn)。
值得注意的是鍵盤事件已經(jīng)從 DOM2 級事件中移出了,起初在 DOM2 級事件的草案版中,鍵盤事件是作為草案的一部分的,但在最終版被移出了,F(xiàn)F 已經(jīng)實現(xiàn)了草案版中的鍵盤事件,值得注意的是在 DOM3 級事件中實現(xiàn)的鍵盤事件與 DOM2 級事件草案版中的鍵盤事件還是存在很大差異的。
在 dom3 級事件中創(chuàng)建一個鍵盤事件對象是通過 createEvent()方法,并傳入 KeyBoardEvent 字符串作為參數(shù),對返回的 event 對象,調(diào)用 initKeyBoadEvent()方法初始化,初始化鍵盤事件的參數(shù)有以下幾個:
type (string) - 要觸發(fā)的事件類型,例如 "keydown"。
bubbles (Boolean) ― 代表事件是否應(yīng)該冒泡。
cancelable (Boolean) ― 代表事件是否可以被取消。
view (AbstractView) ― 被授予事件的是圖。通常值為:document.defaultView。
key (string) ― 按下的鍵對應(yīng)的 code。
location (integer) ― 按下鍵所在的位置。0:默認鍵盤,1 左側(cè)位置,2 右側(cè)位置,3 數(shù)字鍵盤區(qū),4 虛擬鍵盤區(qū),or 5 游戲手柄。
modifiers (string) ― 一個有空格分開的修飾符列表。
repeat (integer) ― 一行中某個鍵被按下的次數(shù)。
請注意的是,在 DOM3 事件中,費掉了 keypress 事件,因此按照下面的方式,你只能模擬鍵盤上的 keydown 和 keyup 事件。
var textbox = document.getElementById("myTextbox"),event;
if (document.implementation.hasFeature("KeyboardEvents", "3.0")){
event = document.createEvent("KeyboardEvent");
event.initKeyboardEvent("keydown", true, true, document.defaultView, "a",0, "Shift", 0);
}
textbox.dispatchEvent(event);
在 FF 下,允許你通過使用 document.createEvent('KeyEvents'),這種方式來創(chuàng)建鍵盤事件,初始化的方法為 initKeyEvent(),這個方法接受 10 個參數(shù),
type (string) ― 要觸發(fā)的事件類型,例如 "keydown"。
bubbles (Boolean) ― 代表事件是否應(yīng)該冒泡。
cancelable (Boolean) ― 代表事件是否可以被取消。
view (AbstractView) ― 被授予事件的是圖. 通常值為:document.defaultView。
ctrlKey (Boolean) ― 代表 ctrol 鍵是否按下。默認 false。
altKey (Boolean) ― 代表 alt 鍵是否按下。默認 false。
shiftKey (Boolean) ― 代表 shift 鍵是否按下。默認 false。
metaKey (Boolean) ― 代表 meta 鍵是否按下。默認 false。
keyCode (integer) ― 鍵按下或釋放時鍵所對應(yīng)的鍵碼。默認是 0;
charCode (integer) ― 按下的鍵的字符所對應(yīng)的 ASCII code。是共 keypress 事件使用的 默認是 0。
鼠標事件和鍵盤事件是在瀏覽器中最長被模擬的事件,但是某些時候同樣需要模擬突變事件和 HTML 事件??梢杂?createEvent('MutationEvents'),來創(chuàng)建一個突變事件對象,可以采用 initMutationEvent() 來初始化這個事件對象,參數(shù)包括 type,bubbles,cancelable, relatedNode,prevValue,newValue,attrName,和 attrChange??梢圆捎孟旅娴姆绞絹砟M一個突變事件:
var event = document.createEvent('MutationEvents');
event.initMutationEvent("DOMNodeInserted", true, false, someNode, "","","",0);
target.dispatchEvent(event);
對于 HTML 事件,直接上代碼。
var event = document.createEvent("HTMLEvents");
event.initEvent("focus", true, false);
target.dispatchEvent(event);
對于突變事件和 HTML 事件是很少在瀏覽器中用到,因為他們收應(yīng)用程序的限制。
在 DOM3 級事件中定義了一類事件稱之為 custom event,我稱之為客戶事件,客戶事件不會原生的被 dom 觸發(fā),而是直接提供,以至于開發(fā)者可以創(chuàng)建他們自己的事件,你可以創(chuàng)建一個自己的客戶事件,通過調(diào)用 createEvent('CustomEvent'),對返回的事件對象調(diào)用,initCustomEvent()方法,其中傳遞四個參數(shù) type,bubbles,cancelable,detail。ps:小弟對這部分理解有限,在這里只是拋磚引玉。
從 IE8,以及更早版本的 IE,都在模仿 DOM 模擬事件的方式:創(chuàng)建事件對象,初始化事件信息,之后觸發(fā)事件。當然 IE 在完成這幾個步驟的過程是不同的。
首先不同于 dom 中創(chuàng)建 event 對象的方法,IE 采用 document.createEventObject()方法,并且沒有參數(shù),返回一個通用的事件對象,接下來要對返回的 event 對象賦值,此時 ie 并沒有提供初始化函數(shù),你只能采用物理方法一個一個的賦值,最后在目標元素上調(diào)用 fireEvent()方法,參數(shù)為兩個:事件處理的名稱和創(chuàng)建的事件對象。當 fireEvent 方法被調(diào)用的時候,event 對象的 srcElement 和 type 屬性將會被自動賦值,其他將需要手動賦值。請看下面的例子:
var btn = document.getElementById("myBtn");
var event = document.createEventObject();
event.screenX = 100;
event.screenY = 0;
event.clientX = 0;
event.clientY = 0;
event.ctrlKey = false;
event.altKey = false;
event.shiftKey = false;
event.button = 0;
btn.fireEvent("onclick", event);
這個例子創(chuàng)建了一個事件對象,之后通過一些信息初始化該事件對象,注意事件屬性的賦值是無序的,對于事件對象來說這些屬性值不是很重要,因為只有事件句柄對應(yīng)的處理函數(shù)(event handler)會用到他們。對于創(chuàng)建鼠標事件、鍵盤事件還是其他事件的事件對象之間是沒有區(qū)別的,因為一個通用的事件對象,可以被任何類型的事件觸發(fā)。
值得注意的是,在 Dom 的鍵盤事件模擬中,對于一個 keypress 模擬事件的結(jié)果不會作為字符出現(xiàn)在 textbox 中,即使對應(yīng)的事件處理函數(shù)已經(jīng)觸發(fā)。
與 DOM 事件模擬相比,個人覺得 IE 的事件模擬更容易讓人記憶和接受,統(tǒng)一的事件模型可以帶來一些便捷。