事件,就是网页中某个特别值得关注的瞬间。事件常常由用户操做或经过其余浏览器功能来触发。
但不多有人知道,也可使用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而在文本框中看到任何字符,即便触发了事件处理程序也没有用。