使用Dojo的Ajax应用开发进阶教程,第5部分: 浏览器中的事件处理2011-01-21 IBM 成富简介: 事件处理是 Ajax 应用中的重要组成部分,也是应用动态变化的源动力。本文详细介绍了浏览器中的事件处理相关的内容,包括注册事件监听器、事件发生之后的传播机制、编写事件监听器等,还介绍了 Dojo 对事件处理提供的支持。最后介绍了与浏览器内存泄露和性能相关的最佳实践。浏览器中的事件是 Ajax 应用动态变化的源动力。用户通过输入设备(主要是键盘和鼠标)与应用进行互动。对于用户不同的动作,如点击鼠标左键、右键、或是按下键盘上的回车键,浏览器会产生与之对应的事件。这些事件按照一定的规则在当前文档树中传播。应用可以根据自己的需要,对特定的事件进行处理,以响应用户的动作。这种事件驱动的方式,不仅在 Web 应用中被使用,在桌面应用中也广泛流行。本文详细介绍了浏览器中事件处理的各个方面,包括事件监听器的注册、事件的传播、事件处理和其它高级话题。本文还介绍了如何使用 Dojo 提供的 dojo.connect()。本文中使用的 Dojo 版本是 1.4。下面首先介绍如何注册事件监听器。注册事件监听器注册事件监听器的目的是在事件发生的时候添加相应的处理逻辑。浏览器中的事件处理采用经典的观察者(Observer)设计模式。对于可能产生的各种事件,Ajax 应用通过脚本在节点上关注自己感兴趣的事件,并添加相应的处理逻辑。当相应的事件发生并传播到监听器注册的节点时,处理逻辑会被调用。由于历史原因、浏览器之间的兼容性问题以及 W3C 的标准化工作,目前注册事件监听器的方式主要有三种,分别是 DOM 级别 0 定义的方式、W3C 规范定义的事件模型和 IE 独有的事件模型。下面分别对这三种方式进行详细的介绍。DOM 级别 0 定义的方式这种事件监听器注册方式是把事件处理方法作为 DOM 节点对象的属性来设置。设置属性就相当于为对应的事件注册了监听器。DOM 节点对象有不同的属性与不同的事件类型相对应,如 onclick对应于鼠标的点击、onsubmit对应于表单的提交、onkeydown对应于键盘上的键被按下等。这种事件监听器注册方式由于出现得最早,有着很好的浏览器兼容性,使用起来也比较简单。它的问题是由于事件处理方法被设置为 DOM 节点对象的属性,因此对一个 DOM 节点的每种事件,最多只能有一个事件处理方法。之后设置的方法会覆盖掉之前的方法。对于一个多人开发的比较复杂的 Ajax 应用来说,这会是一个不小的问题。很可能某个开发人员添加的事件处理方法被另外的开发人员无意中覆盖,造成难以调试的问题。另外这种方式只支持事件的冒泡阶段,不支持捕获阶段。W3C 规范定义的事件模型在 W3C 的 DOM 级别 2 规范中引入了与浏览器事件相关的内容。这其中一个重要的接口就是 EventTarget,用来表示一个事件的目标。对于一个事件目标,可以在其上注册多个事件监听器。DOM 中的节点(Node)实现了此接口。因此,文档树中的任何节点都可以作为事件目标,从而在其上注册事件监听器。注册事件监听器是通过 EventTarget接口的 addEventListener(type, listener, useCapture)方法来完成的。该方法的参数 type表示的是事件的类型,如 click、submit和 keypress等;参数 listener表示的是事件的处理方法;参数 useCapture表示是否启用事件捕获。这三个参数都是必须的。关于事件捕获和冒泡的细节,下面章节会介绍。与 addEventListener()对应的是 removeEventListener(),用来从事件目标中删除监听器,其参数与 addEventListener()相同。使用 W3C 规范定义的事件模型的最大好处是可以为每个节点的每个事件注册多个监听器。这些监听器不会互相影响。当事件发生的时候,这些监听器都会被触发,但是具体的顺序是不确定的。另外这也是符合标准的做法,并且同时支持事件的捕获和冒泡。不过最大的问题是 IE 并不支持此事件模型。IE 独有的事件模型IE 采用了与 W3C 规范不同的事件模型。该模型与 W3C 规范定义的事件模型有点类似。它使用 attachEvent(type, listener)和 detachEvent(type, listener)两个方法来完成事件监听器的注册和删除。与 W3C 规范中的 addEventListener()和 removeEventListener()方法相比,这两个方法都少了一个参数。这是由于 IE 并不支持事件的捕获。另外事件的类型也必须以“on”开头,如 onclick、onsubmit和 onkeypress等。IE 独有的事件模型也支持为每个元素的每个事件注册多个监听器。不过该模型只在 IE 中有效,在其它浏览器中,需要使用 W3C 规范定义的事件模型。代码清单 1 中给出了如何分别使用这三种方式为一个元素注册鼠标点击事件的监听器。清单 1. 三种事件监听器注册方式示例
var node = document.getElementById("myDiv");
node.onclick = function() {
alert("DOM 级别 0 事件注册");
};
if (node.addEventListener) {
node.addEventListener("click", function() {
alert("W3C 事件模型");
}, false);
}
if (node.attachEvent) {
node.attachEvent("onclick", function() {
alert("IE 事件模型");
});
}
在介绍了如何注册事件监听器之后,下面介绍事件发生之后在当前文档树中的传播方式。