事件,就是網頁中某個特別值得關注的瞬間。事件常常由用戶操做或經過其餘瀏覽器功能來觸發。
但不多有人知道,也可使用JavaScript 在任意時刻來觸發特定的事件,而此時的事件就如同瀏覽器建立的事件同樣。也就是說,這些事件該冒泡還會冒泡,並且照樣可以致使瀏覽器執行已經指定的處理它們的事件處理程序。在測試Web 應用程序,模擬觸發事件是一種極其有用的技術。DOM2 級規範爲此規定了模擬特定事件的方式,IE九、Opera、Firefox、Chrome 和Safari 都支持這種方式。IE 有它本身模擬事件的方式。api
能夠在document 對象上使用createEvent()方法建立event 對象。這個方法接收一個參數,即表示要建立的事件類型的字符串。在DOM2 級中,全部這些字符串都使用英文複數形式,而在DOM3級中都變成了單數。這個字符串能夠是下列幾字符串之一。瀏覽器
要注意的是,「DOM2 級事件」並無專門規定鍵盤事件,後來的「DOM3 級事件」中才正式將其做爲一種事件給出規定。IE9 是目前惟一支持DOM3 級鍵盤事件的瀏覽器。不過,在其餘瀏覽器中,在現有方法的基礎上,能夠經過幾種方式來模擬鍵盤事件。
在建立了event 對象以後,還須要使用與事件有關的信息對其進行初始化。每種類型的event 對象都有一個特殊的方法,爲它傳入適當的數據就能夠初始化該event 對象。不一樣類型的這個方法的名字也不相同,具體要取決於createEvent()中使用的參數。
模擬事件的最後一步就是觸發事件。這一步須要使用dispatchEvent()方法,全部支持事件的DOM 節點都支持這個方法。調用dispatchEvent()方法時,須要傳入一個參數,即表示要觸發事件的event 對象。觸發事件以後,該事件就躋身「官方事件」之列了,於是可以照樣冒泡並引起相應事件處理程序的執行。測試
建立新的鼠標事件對象併爲其指定必要的信息,就能夠模擬鼠標事件。建立鼠標事件對象的方法是爲createEvent()傳入字符串"MouseEvents"。返回的對象有一個名爲initMouseEvent()方法,用於指定與該鼠標事件有關的信息。這個方法接收15 個參數,分別與鼠標事件中每一個典型的屬性一一對應;這些參數的含義以下。編碼
顯而易見,initMouseEvent()方法的這些參數是與鼠標事件的event 對象所包含的屬性一一對應的。其中,前4 個參數對正確地激發事件相當重要,由於瀏覽器要用到這些參數;而剩下的全部參數只有在事件處理程序中才會用到。當把event 對象傳給dispatchEvent()方法時,這個對象的target屬性會自動設置。下面,咱們就經過一個例子來了解如何模擬對按鈕的單擊事件。spa
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的瀏覽器中,也能夠經過相同的方式來模擬其餘鼠標事件(例如dblclick)。對象
前面曾經提到過,「DOM2 級事件」中沒有就鍵盤事件做出規定,所以模擬鍵盤事件並無現成的思路可循。「DOM2 級事件」的草案中原本包含了鍵盤事件,但在定稿以前又被刪除了;Firefox 根據其草案實現了鍵盤事件。須要提請你們注意的是,「DOM3 級事件」中的鍵盤事件與曾包含在「DOM2 級事件」草案中的鍵盤事件有很大區別。
DOM3 級規定,調用createEvent()並傳入"KeyboardEvent"就能夠建立一個鍵盤事件。返回的事件對象會包含一個initKeyEvent()方法,這個方法接收下列參數。blog
因爲DOM3級不提倡使用keypress 事件,所以只能利用這種技術來模擬keydown 和keyup 事件。繼承
var textbox = document.getElementById("myTextbox"), event; //以DOM3 級方式建立事件對象 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);
運行一下
這個例子模擬的是按住Shift 的同時又按下A 鍵。在使用document.createEvent
("KeyboardEvent")以前,應該先檢測瀏覽器是否支持DOM3 級事件;其餘瀏覽器返回一個非標準的KeyboardEvent 對象。
在Firefox 中,調用createEvent()並傳入"KeyEvents"就能夠建立一個鍵盤事件。返回的事件對象會包含一個initKeyEvent()方法,這個方法接受下列10 個參數。教程
將建立的event 對象傳入到dispatchEvent()方法就能夠觸發鍵盤事件,以下面的例子所示。seo
//只適用於Firefox var textbox = document.getElementById("myTextbox") //建立事件對象 var event = document.createEvent("KeyEvents"); //初始化事件對象 event.initKeyEvent("keypress", true, true, document.defaultView, false, false, false, false, 65, 65); //觸發事件 textbox.dispatchEvent(event);
運行一下
在Firefox 中運行上面的代碼,會在指定的文本框中輸入字母A。一樣,也能夠依此模擬keyup 和keydown 事件。
在其餘瀏覽器中,則須要建立一個通用的事件,而後再向事件對象中添加鍵盤事件特有的信息。
例如:
var textbox = document.getElementById("myTextbox"); //建立事件對象 var event = document.createEvent("Events"); //初始化事件對象 event.initEvent(type, bubbles, cancelable); event.view = document.defaultView; event.altKey = false; event.ctrlKey = false; event.shiftKey = false; event.metaKey = false; event.keyCode = 65; event.charCode = 65; //觸發事件 textbox.dispatchEvent(event);
以上代碼首先建立了一個通用事件,而後調用initEvent()對其進行初始化,最後又爲其添加了鍵盤事件的具體信息。在此必需要使用通用事件,而不能使用UI 事件,由於UI 事件不容許向event對象中再添加新屬性(Safari 除外)。像這樣模擬事件雖然會觸發鍵盤事件,但卻不會向文本框中寫入文本,這是因爲沒法精確模擬鍵盤事件所形成的。
雖然鼠標事件和鍵盤事件是在瀏覽器中最常常模擬的事件,但有時候一樣須要模擬變更事件和HTML 事件。要模擬變更事件, 可使用createEvent("MutationEvents") 建立一個包含initMutationEvent() 方法的變更事件對象。這個方法接受的參數包括: type 、bubbles 、cancelable、relatedNode、preValue、newValue、attrName 和attrChange。下面來看一個模擬變更事件的例子。
var event = document.createEvent("MutationEvents"); event.initMutationEvent("DOMNodeInserted", true, false, someNode, "","","",0); targ et.dispatchEvent(event);
以上代碼模擬了DOMNodeInserted 事件。其餘變更事件也均可以照這個樣子來模擬,只要改一改參數就能夠了。
要模擬HTML 事件,一樣須要先建立一個event 對象——經過createEvent("HTMLEvents"),而後再使用這個對象的initEvent()方法來初始化它便可,以下面的例子所示。
var event = document.createEvent("HTMLEvents"); event.initEvent("focus", true, false); targ et.dispatchEvent(event);
這個例子展現瞭如何在給定目標上模擬focus 事件。模擬其餘HTML 事件的方法也是這樣。
瀏覽器中不多使用變更事件和HTML 事件,由於使用它們會受到一些限制。
DOM3 級還定義了「自定義事件」。自定義事件不是由DOM 原生觸發的,它的目的是讓開發人員建立本身的事件。要建立新的自定義事件,能夠調用createEvent("CustomEvent")。返回的對象有一個名爲initCustomEvent()的方法,接收以下4 個參數。
能夠像分派其餘事件同樣在DOM 中分派建立的自定義事件對象。例如:
var div = document.getElementById("myDiv"), event; EventUtil.addHandler(div, "myevent", function(event) { alert("DIV: " + event.detail); }); EventUtil.addHandler(document, "myevent", function(event) { alert("DOCUMENT: " + event.detail); }); if (document.implementation.hasFeature("CustomEvents", "3.0")) { event = document.createEvent("CustomEvent"); event.initCustomEvent("myevent", true, false, "Hello world!"); div.dispatchEvent(event); }
運行一下
這個例子建立了一個冒泡事件"myevent"。而event.detail 的值被設置成了一個簡單的字符串,而後在<div>元素和document 上偵聽這個事件。由於initCustomEvent()方法已經指定這個事件應該冒泡,因此瀏覽器會負責將事件向上冒泡到document。
支持自定義DOM事件的瀏覽器有IE9+和Firefox 6+。
在IE8 及以前版本中模擬事件與在DOM中模擬事件的思路類似:先建立event 對象,而後爲其指定相應的信息,而後再使用該對象來觸發事件。固然,IE 在實現每一個步驟時都採用了不同的方式。
調用document.createEventObject()方法能夠在IE 中建立event 對象。但與DOM方式不一樣的是,這個方法不接受參數,結果會返回一個通用的event 對象。而後,你必須手工爲這個對象添加全部必要的信息(沒有方法來輔助完成這一步驟)。最後一步就是在目標上調用fireEvent()方法,這個方法接受兩個參數:事件處理程序的名稱和event 對象。在調用fireEvent()方法時,會自動爲event 對象添加srcElement 和type 屬性;其餘屬性則都是必須經過手工添加的。換句話說,模擬任何IE 支持的事件都採用相同的模式。例如,下面的代碼模擬了在一個按鈕上觸發click 事件過程。
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);
運行一下
這個例子先建立了一個event 對象,而後又用一些信息對其進行了初始化。注意,這裏能夠爲對象隨意添加屬性,不會有任何限制——即便添加的屬性IE8 及更早版本並不支持也無所謂。在此添加的屬性對事件沒有什麼影響,由於只有事件處理程序纔會用到它們。
採用相同的模式也能夠模擬觸發keypress 事件,以下面的例子所示。
var textbox = document.getElementById("myTextbox"); //建立事件對象 var event = document.createEventObject(); //初始化事件對象 event.altKey = false; event.ctrlKey = false; event.shiftKey = false; event.keyCode = 65; //觸發事件 textbox.fireEvent("onkeypress", event);
運行一下
因爲鼠標事件、鍵盤事件以及其餘事件的event 對象並無什麼不一樣,因此可使用通用對象來觸發任何類型的事件。不過,正如在DOM中模擬鍵盤事件同樣,運行這個例子也不會因模擬了keypress而在文本框中看到任何字符,即便觸發了事件處理程序也沒有用。