专注VB编程开发20年

专注VB编程开发20年

一、DOM 级别 2 的事件模拟

利用 DOM2 的标准我们可以模拟这些类型的事件:HTMLEvents,MutationEvents,UIEvents 和 MouseEvents。而事件的模拟基本是三步:createEvent,initEvent 和 dispatchEvent。例如我们可以用下面的方式模拟 HTML 事件:

var event = document.createEvent("HTMLEvents");
event.initEvent("focus", true, false);
element.dispatchEvent(event);

其中 HTML 事件包括这些:load,unload,abort,error,select,change,submit,reset,focus,blur,resize,scroll。

而变动事件的模拟的例子如下:

var event = document.createEvent("MutationEvents");
event.initMutationEvent("DOMNodeInserted", true, false, someNode, "","","",0);
element.dispatchEvent(event);

其中变动事件包括这些:DOMSubtreeModified,DOMNodeInserted,DOMNodeRemoved,DOMNodeRemovedFromDocument,DOMNodeInsertedIntoDocument,DOMAttrModified,DOMCharacterDataModified。

上面这两类事件用得不多的,我们经常需要模拟的是鼠标事件。例如:

var event = document.createEvent("MouseEvents");
event.initMouseEvent("click", true, true, document.defaultView, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
element.dispatchEvent(event);

initMouseEvent 的 15 个参数中,第一个指该事件的名称,第二个指该事件是否冒泡,而第三个指该事件是否可取消。其它的参数的意义可以参考 DOM2 文档。如果我们只需要模拟该事件而不关心该事件出现的坐标等,可以偷懒用 initUIEvent(这是由于 MouseEvent 对象继承自 UIEvent 对象),如下:

var event = document.createEvent("MouseEvents");
event.initUIEvent("click", true, true, document.defaultView, 0);
element.dispatchEvent(event);

或者更加偷懒地使用 initEvent(因为 UIEvent 对象也是继承自最基本的 Event 对象):

var event = document.createEvent("MouseEvents");
event.initEvent("click", true, true);
element.dispatchEvent(event);
二、DOM 级别 3 的事件模拟

在 DOM3 中,增加了 KeyboardEvent,WheelEvent,CustomEvent 等类型事件的模拟。注意对于事件类型名称 DOM2 中使用复数形式,而 DOM3 中使用单数形式。同时,对于 DOM2 中的 MutationEvents,UIEvents 和 MouseEvents,在 DOM3 中同样可以用单数形式的 MutationEvent,UIEvent 和 MouseEvent(DOM3 中没有 HTMLEvent,只涉及到 FocusEvent)。列个表对比并总结如下:

 下面的例子模拟了键盘的 keydown 事件(按下 Shift+a):

event = document.createEvent("KeyboardEvent");
event.initKeyboardEvent("keydown", true, true, document.defaultView, "a", 0, "Shift", 0);
element.dispatchEvent(event);

类似地也可以模拟 keyup 和 keypress 事件。DOM3 标准中的 initKeyboardEvent 函数参数有过改动,这导致各个浏览器的兼容性出现问题。我们可以参考这里的 gist 代码:Cross-browser initKeyboardEvent

三、事件模拟的浏览器支持

Firefox,Chrome,Safari,Opera 支持 DOM2 的事件模拟,但是基本不支持 DOM3 新的事件模拟。而 IE9 支持 DOM2 和 DOM3 的事件模拟,但是 IE8 及其之前的版本完全不支持 DOM2 和 DOM3 的事件模拟。在旧版本的 IE 中可以使用 createEventObject 和 fireEvent 方法实现事件模拟。

我们可以用 document.implementation.hasFeature 方法检测浏览器对这些事件模拟的支持情况。例如:

var hasDOM2HTMLEvents = document.implementation.hasFeature("HTMLEvents", "2.0");
var hasDOM3KeyboardEvent = document.implementation.hasFeature("KeyboadEvent", "3.0");

但实际上,这种方法还是不够可靠,最后还是用特性检测比较好。

参考资料:
[1] DOM Level 2 Events - 1. Document Object Model Events
[2] DOM Level 2 Events - Appendix A: IDL Definitions
[3] DOM Level 3 Events - #events-DocumentEvent-createEvent
[4] DOM Level 3 Events - #event-types
[5] DOM Level 3 Events - #event-interfaces
[6] document.createEvent - Document Object Model (DOM) | MDN
[7] DOM Level 3 Events support in IE9 - IEBlog - Site Home - MSDN Blogs
[8] Internet Explorer: Testing Center #domevents

02-02 04:14