目录
内存和性能
事件委托
对“事件处理程序过多”问题的解决方案就是事件委托。事件委托利用了事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。例如, click 事件会一直冒泡到 document 层次。也就是说,我们可以为整个页面指定一个 onclick 事件处理程序,而不必给每个可单击的元素分别添加事件处理程序。
<ul id="myLinks">
<li id="goSomewhere">Go somewhere</li>
<li id="doSomething">Do something</li>
<li id="sayHi">Say hi</li>
</ul>
var list = document.getElementById("myLinks");
EventUtil.addHandler(list, "click", function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
switch(target.id){
case "doSomething":
document.title = "I changed the document's title";
break;
case "goSomewhere":
location.href = "http://www.wrox.com";
break;
case "sayHi":
alert("hi");
break;
}
});
移除事件处理程序
内存中留有那些过时不用的“空事件处理程序”(dangling event handler),也是造成 Web 应用程序内存与性能问题的主要原因。
//从文档中移除带有事件处理程序的元素时
<div id="myDiv">
<input type="button" value="Click Me" id="myBtn">
</div>
<script type="text/javascript">
var btn = document.getElementById("myBtn");
btn.onclick = function(){
//先执行某些操作
btn.onclick = null; //移除事件处理程序
document.getElementById("myDiv").innerHTML = "Processing...";
};
</script>
模拟事件
DOM中的事件模拟
模拟鼠标事件
创建新的鼠标事件对象并为其指定必要的信息,就可以模拟鼠标事件。创建鼠标事件对象的方法是为 createEvent()传入字符串"MouseEvents"。返回的对象有一个名为 initMouseEvent()方法,用于指定与该鼠标事件有关的信息。
var btn = document.getElementById("myBtn");
//创建事件对象
var event = document.createEvent("MouseEvents");
//初始化事件对象
//接收 15 个参数,分别与鼠标事件中每个典型的属性一一对应
event.initMouseEvent("click", true, true, document.defaultView, 0, 0, 0, 0, 0,
false, false, false, false, 0, null);
//触发事件
btn.dispatchEvent(event);
模拟键盘事件
DOM3 级规定,调用 createEvent()并传入"KeyboardEvent"就可以创建一个键盘事件。返回的事件对象会包含一个 initKeyEvent()方法,这个方法接收下列参数。
type(字符串):表示要触发的事件类型,如"keydown"。
bubbles(布尔值):表示事件是否应该冒泡。为精确模拟鼠标事件,应该设置为 true。
cancelable(布尔值):表示事件是否可以取消。为精确模拟鼠标事件,应该设置为 true。
view (AbstractView ):与事件关联的视图。这个参数几乎总是要设置为 document.defaultView。
key(布尔值):表示按下的键的键码。
location(整数):表示按下了哪里的键。 0 表示默认的主键盘, 1 表示左, 2 表示右, 3 表示数字键盘, 4 表示移动设备(即虚拟键盘), 5 表示手柄。
modifiers(字符串):空格分隔的修改键列表,如"Shift"。
repeat(整数):在一行中按了这个键多少次。
//按 住 Shift 的 同 时 又 按 下 A 键
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);
模拟其他事件
模拟变动事件,可以使用createEvent("MutationEvents") 创建一个含initMutationEvent() 方法的变动事件对象 。这个方法接受的参数包括 :type 、bubbles 、cancelable、relatedNode、preValue、newValue、attrName 和 attrChange。
var event = document.createEvent("MutationEvents");
event.initMutationEvent("DOMNodeInserted", true, false, someNode, "","","",0);
target.dispatchEvent(event);
模拟HTML事件,需要先创建一个 event 对象——通过createEvent("HTMLEvents"),然后再使用这个对象的initEvent()方法来初始化它即可
var event = document.createEvent("HTMLEvents");
event.initEvent("focus", true, false);
target.dispatchEvent(event);
自定义 DOM 事件
自定义事件不是由 DOM 原生触发的,它的目的是让开发人员创建自己的事件。要创建新的自定义事件,可以调用 createEvent("CustomEvent")。返回的对象有一个名为 initCustomEvent()的方法,接收如下 4 个参数
type(字符串):触发的事件类型,例如"keydown"。
bubbles(布尔值):表示事件是否应该冒泡。
cancelable(布尔值):表示事件是否可以取消。
detail(对象):任意值,保存在 event 对象的 detail 属性中。
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);
}
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);