Skip to content

javascript DOM事件模型

前些天有人电话里问我dom事件模型,其实这个东西我之前肯定是有看过,好好的理过的。只不过,公司面对的客户群就是纯ie的的客户,所以对标准浏览器的事件模型给忘记了。当时只回答了ie下是冒泡(Bubbling),标准浏览器是捕获(Capture)。

回头去搜了一下,标准浏览器还有一个冒泡(Bubbling)的过程。而Netscape Navigatior才只有捕获。

我们都知道DOM(文档对象模型)是一个树形结构,当一个html元素产生一个事件时,这个事件会在元素节点与根节点之间的路径传播,路径中的节点都会触发这个事件。

DOM事件模型主要有三种模型:冒泡、捕获和标准事件模型。

之前浏览器都是有自己的事件模型,到DOM Level3后,才陆陆续续的支持DOM标准的事件模型,即捕获与冒泡型。这两种事件模型肯定是各有优缺点了,所以标准浏览器的事件模型会采用两者的结合体。现在主流的浏览器firefox,opera,safari都支持标准的DOM事件处理模型,而ie仍使用自己的模型。

[html] [/html]
<div class="wrapper">
	<div class="head">
		head
	</div>
	<div class="mainbody" >
		lalsdfjasdk jfklsdajf lkasjdf  dsf sdf <br/>
		lalsdfjasdk jfklsdajf lkasjdf<br/>
		lalsdfjasdk jfklsdajf lkasjdf<br/>
	<button class="btn">button</button>
	</div>
</div>
这段html代码在IE下事件的传播路径(冒泡)是这样的:

button.btn - > div.mainbody - > div.wrapper - > body - >document

在标准浏览器下事件的传播路径会是这样:

window - > document - > body - > div.wrapper - > div.mainbody - > button.btn

  • > div.mainbody - > div.wrapper - > body - >document - > window

javascript使用事件驱动,先给一个元素添加事件监听函数,当这个元素的对应事件对触发后,就会调用添加的事件监听函数。

下面就是javascript中给元素添加事件监听函数的方法:

直接在html元素上添加

[html] [/html]
<button id="sbtBtn" onclick="btnClick();" class="btn">button</button>
用相应的js属性
[javascript] [/javascript]
document.getElementById("sbtBtn").onclick = function(){
//add your code
}
用注册函数
[javascript] [/javascript]
document.getElementById("sbtBtn").addEventListener("click",
    function(){
//add your code
    },true);
这三种方法在作用域以及事件传播等都是有区别,而这个区别就是DOM level 0 ,DOM level 2事件模型的区别了。关于这个区别,我在最近的技术支持的过程中有一点体会。这也是我立马来看DOM事件模型的原因了。

** DOM Level 0**

像上面前两种方式,都是这个级别的事件模型了。一般说来,在这个监听函数里返回一个false值,会阻止浏览器默认的执行动作,this指向目标元素。

从技术上来说,W3C的DOM标准并不支持上述最原始的添加事件监听函数的方式,这些都是在DOM标准形成前的事件模型。尽管没有正式的W3C标准,但这种事件模型仍然得到广泛应用,这就是我们通常所说的0级DOM。

DOM 级别 0 不是 W3C 规范。而仅仅是对在 Netscape Navigator 3.0 和 Microsoft Internet Explorer 3.0 中的等价功能性的一种定义。

DOM 发展过程中的关键角色有:ArborText、IBM、Inso EPS、JavaSoft、Microsoft、Netscape、Novell、the Object Management Group、SoftQuad、Sun Microsystems 以及 Texcel。

W3C 的 DOM 级别 1 建立于此功能性之上。 DOM Level 1

DOM级别1于1998年10月1日成为W3C推荐标准。1级DOM标准中并没有定义事件相关的内容,所以没有所谓的1级DOM事件模型。** **

DOM 级别 1 专注于 HTML 和 XML 文档模型。它含有文档导航和处理功能。

DOM 级别 1 于 1998 年 10 月 1 日成为 W3C 推荐标准。

第二版的工作草案在 2000 年 9 月 29 日。 **DOM Level 2 **

如前面所述,标准浏览器分捕获和冒泡两个阶段,前面添加事件监听的第三种方法就是这个级别的实现方式。但是这个方法我们还要详细的去探究这个方法的用法:

addEventListener(eventType,handler,useCapture),有三个参数,其中第三个参数决定了事件的注册函数在哪个事件传播阶段触发,如果为true则在捕获阶段,反之则在冒泡阶段。当一个目标注册了捕获阶段的监听函数,如果其祖先节点也注册了,那么在传播的过程中就会执行这些函数。

在执行监听函数时,会传入一个event对象,其实有一些常用的属性我们会经常用到:

type:

发生事件的类型,如click , mouseover, mouseout等

target:

发生事件的节点可能与currentTarget不同

currentTarget:

正在处理事件的节点,如果在capturing阶段和冒泡阶段处理事件,这个属性就与target属性不同。在事件监听函数中应该用这个属性而不是this

stopPropagation():

可以阻止事件从当前正在处理他的节点传播

preventDefault():

阻止浏览器执行与事件相关的默认动作,与0级DOM中返回false一样

clientX, clientY:

鼠标相对于浏览器的x坐标y坐标

screenX, screenY:

鼠标相对于显示器左上角的x坐标y坐标

IE下的处理方式

IE下没有addEventListener,但是有自己类似的方法:attachEvent,这个方法只有两个参数,第一个参数为事件类型的前面需要加"on",由于 ie下没有捕获,所以没有类似标准浏览器的第三个参数。

IE上可以对元素进行多次同样的绑定,标准浏览器只会绑定一次。ie下event对象不是事件处理程序传入的参数,而是全局的变量:window.event,例如中断冒泡用window.event.cancelBubble = true.

event常用属性

type: 兼容DOM的type属性

srcElement:

兼容DOM的target属性

clientX, clientY:

兼容DOM的clientX, clientY属性

cancelBubble:

布尔值,设为true同调用stopPropagation()

returnValue:

布尔值,设为false同调用preventDefault()

卸载方法

Object.removeEventListener(eventType,handler,useCapture);//DOM标准的事件卸载方式
Object.detachEvent(eventType,handler);//IE内核的事件卸载方式

关于事件类型,各大浏览器支持的情况:Event compatibility tables

参考 :

1、W3C DOM 活动

2、《JavaScript高级程序设计(第2版)》