1 事件流
事件流描述的是从页面中接受事件的顺序。IE和NetScape采用了相反的实现机制,IE中采用的是事件冒泡,NetScape采用的是事件捕获。
事件冒泡:
事件从最具体的元素,逐级传递到最不具体的元素。
事件捕获:
事件捕获的目的是在事件到达预定目标之前捕获它。事件捕获的思想是越不具体的节点更早接受到事件,而最具体的节点最后接受到事件。
DOM事件流:
DOM事件流定义了三个阶段:事件捕获阶段、处于目标阶段、事件冒泡阶段。事件捕获是为截获事件提供机会。
2 事件处理程序
事件是用户或浏览器自身执行的动作。而事件处理程序是对事件的响应的一个函数。
2.1 HTML事件处理程序
HTML中每个元素支持的事件都可以使用一个与相应事件处理程序同名的特性指定。
- 事件处理程序中的代码在执行时有权访问全局作用域中的任何代码。
- 事件处理程序中包含了一个事件对象event。
- 在函数内部,this就代表事件的目标元素。
- 当然我们可以用with拓展作用域链。
然而在HTML中指定事件处理程序有两个缺点:
- 存在一个时差问题。当触发事件是,相应事件处理程序还不具备执行条件。可以像下面这样解决。加try-catch
- 扩展作用域链在不同浏览器上会有不同的结果。
- 把HTML代码和JavaScript代码耦合起来了。
2.2 DOM0 级事件处理程序(JavaScript事件处理程序)
需要获取被操作对象的引用。如下:
也可以删除事件处理程序:
2.3 DOM2级事件处理程序
DOM2级事件处理程序提供了两个方法addEventListener()、removeEventLister()。
两个方法的参数一样,都是三个,分别为:要处理的事件名、事件处理程序、布尔值(true表示是在事件捕获阶段调用事件处理程序;false表示是在事件冒泡阶段调用事件处理程序)
通过addEventListener()添加的事件处理程序只能使用removeEventListener来删除。且传入的参数必须一样(意味着传入匿名函数不能被删除)。
大多数情况下都是将事件处理程序添加到事件冒泡阶段。除非想要截获事件时才将事件处理程序添加到事件捕获阶段。
2.4 IE事件处理程序
IE也提供了attachEvent(),detachEvent() 两个方法来添加事件处理程序。例子:
参数区别
需要注意的是attachEvent的第一个参数直接是onclick,而不是Dom2级事件处理程序的click.
作用域区别
另外,通过attachEvent与dom0或dom2事件处理程序的区别在于事件处理程序的作用域。dom0或dom2事件处理程序是在其所属的元素的作用域内运行的,而IE事件处理程序是在全局作用域中运行的。下面例子就说明了这个问题:
执行顺序的区别
通过attachEvent添加的事件处理程序的执行顺序不是按添加顺序执行的,而是反过来执行的。
通过detachEvent移除事件处理程序时,参数要和用attachEvent添加事件处理程序一样(所以不能删除匿名函数)。
2.5 跨浏览器的事件处理程序
如何使用?
当然这个跨浏览器的事件处理程序没有考虑所以的浏览器问题,比如Ie中的作用域问题。
3 事件对象
事件对象(event),包含着所以与事件有关的信息。如导致事件的元素,事件的类型等。
3.1 DOM中事件对象
(1)兼容DOM的浏览器会将event传入到事件处理程序中。下面是事件对象的属性及方法:
(2) 在事件处理程序内部,this始终等于currentTarget的值,而target只包含事件的事件目标。比如事件处理程序存在于按钮的父节点中时:
(3) 在需要一个函数中处理多个事件是可以使用type属性。
(4) 要阻止事件的默认行为可以使用preventDefault()。例如阻止链接导航:
(5) 使用stopPropagtion()方法来立即阻止事件在dom层次的传递。
(6) 使用事件对象的eventPhase属性来确定事件当前正处于事件流的那个阶段。eventPhase为1时表示处于事件捕获阶段,eventPhase为2时表示处于目标对象,为3时表示处于冒泡阶段。
3.2 IE中事件对象
event对象的获取
- 使用DOM0级方法添加事件处理程序时,event对象作为window对象的一个属性。
- 使用ie的attachEvent添加事件处理程序时,event对象会作为一个参数传入。当然也可以通过window对象获取event。
- 使用HTML特性添加事件处理程序时,可以通过变量event访问event对象。
ie中event对象共有属性:
(1)不要认为this始终等于事件目标(因为事件处理程序的作用域是根据指定它的方式确定的)。最好用event.srcElement保险一些。比如下面:
(2) ie中event的returnValue属性相当于Dom中event的preventDefault()方法,用来阻止执行默认行为。
(3)cancelBubble相当于Dom中event的stopPropagtion()方法,用来阻止事件在dom层级的传递。然而,ie中不支持事件捕获,只支持事件冒泡。
3.3 跨浏览器的事件对象
IE中event对象的全部信息和方法dom中的event对象都有,只不过实现方式不一样。
实现跨浏览器的事件对象如下:
var EventUtil = {
addHandler: function<