DOM事件模型主要包含4个方面的内容,分别是:
下面一一了解下:
首先,什么是DOM?文档对象模型(DOM)是表示文档(比如HTML和XML)和访问、操作构成文档的各种元素的应用程序接口(API)。一般的,支持Javascript的所有浏览器都支持DOM。
在DOM眼中,HTML跟XML一样是一种树形结构的文档,<html>是根(root)节点,<head>、<title>、<body>是<html>的子(children)节点,互相之间是兄弟(sibling)节点;<body>下面才是子节点<table>、<span>、<p>等等。如下图:
DOM下,HTML文档各个节点被视为各种类型的Node对象。每个Node对象都有自己的属性和方法,利用这些属性和方法可以遍历整个文档树。由于HTML文档的复杂性,DOM定义了nodeType来表示节点的类型。这里列出Node常用的几种节点类型:
接口 |
nodeType常量 |
nodeType值 |
备注 |
Element |
Node.ELEMENT_NODE |
1 |
元素节点 |
Text |
Node.TEXT_NODE |
3 |
文本节点 |
Document |
Node.DOCUMENT_NODE |
9 |
document |
Comment |
Node.COMMENT_NODE |
8 |
注释的文本 |
DocumentFragment |
Node.DOCUMENT_FRAGMENT_NODE |
11 |
document片断 |
Attr |
Node.ATTRIBUTE_NODE |
2 |
节点属性 |
1、 事件流
DOM(文档对象模型)结构是一个树型结构,当一个 HTML元素产生一个事件时,该事件会在元素结点与根结点之间的路径传播,路径所经过的结点都会收到该事件,这个传播过程可称为DOM事件流。
2、 主流浏览器的事件模型
直到DOM Level3中规定后,多数主流浏览器才陆陆续续支持DOM标准的事件处理模型——捕获型与冒泡型。
目前除IE浏览器外,其它主流的Firefox,Opera,Safari都支持标准的DOM事件处理模型。IE仍然使用自己的模型,即冒泡型,它模型的一部份被DOM采用,这点对于开发者来说也是有好处的,只使用DOM标准,IE都共有的事件处理方式才能有效的跨浏览器。
冒泡型事件(Bubbling):从DOM树型结构上理解,就是事件由叶子结点沿祖先结点一直向上传递直到根结点;从浏览器界面视图HTML元素排列层次上理解就是事件由具有从属关系的最确定的目标元素一直传递到最不确定的目标元素。
捕获型事件(Capturing):NetscapeNavigator的实现,它与冒泡型刚好相反,由DOM树最顶层元素一直到最精确的元素。
DOM标准事件模型:因为两个不同的模型都有其优点和解释,DOM标准支持捕获型与冒泡型,可以说是它们两者的结合体。它可以在一个DOM元素上绑定多个事件处理器,并且在处理函数内部,this关键字仍然指向被绑定的DOM元素,另外处理函数参数列表的第一个位置传递事件event对象。
首先是捕获式传递事件,接着是冒泡式传递,所以,如果一个处理函数既注册了捕获型事件的监听,又注册冒泡型事件监听,那么在DOM事件模型中它就会被调用两次。
Javascript的DOM事件流主要经历三个阶段,分别是事件捕获阶段、目标出发阶段和时间冒泡阶段。注意,所有事件都经过捕获阶段和目标阶段,但并不是所有的时间都会经过冒泡阶段。
3、 事件对象
在IE浏览器中事件对象是window对象的一个属性event,并且event对象只能在事件发生时候被访问,所有事件处理完后,该对象就消失了。而标准的DOM中规定event必须作为惟一的参数传给事件处理函数。故为了实现兼容性,通常采用下面的方法:
functionsomeHandle(event) {
if(window.event)
event=window.event;
}
说明:
在两种浏览器处理事件中,type属性是各种浏览器所兼容的,他表示获取的事件类型,返回字符串。
在检测Shift,Alt,Ctrl三个键时,两种浏览器事件使用的方法也是一样的。
在IE中,事件的对象包含在event的srcElement属性中,而在标准的DOM浏览器中,对象包含在target属性中。
为了处理两种浏览器兼容性,举例如下:
function handle(oEvent){
if(window.event) oEvent =window.event; //处理兼容性,获得事件对象
var oTarget;
if(oEvent.srcElement) //处理兼容性,获取事件目标
oTarget =oEvent.srcElement;
else
oTarget = oEvent.target;
alert(oTarget.tagName); //弹出目标的标记名称
}
window.onload = function(){
var oImg =document.getElementsByTagName(“img”)[0];
oImg.onclick = handle;
}
4、 注册与移除事件监听器
IE下注册多个事件监听器与移除监听器方法
IE浏览器中HTML元素有个attachEvent方法允许外界注册该元素多个事件监听器,例如:element.attachEvent(‘onclick’, observer);
要移除先前注册的事件的监听器,调用element的detachEvent方法即可,参数相同,例如:element.detachEvent(‘onclick’, observer);
DOM标准下注册多个事件监听器与移除监听器方法
实现DOM标准的浏览器与IE浏览器中注册元素事件监听器方式有所不同,它通过元素的addEventListener方法注册,该方法既支持注册冒泡型事件处理,又支持捕获型事件处理。
element.addEventListener(‘click’, observer,useCapture);
addEventListener方法接受三个参数。第一个参数是事件名称,值得注意的是,这里事件名称与IE的不同,事件名称是没‘on’开头的;第二个参数observer是回调处理函数;第三个参数注明该处理回调函数是在事件传递过程中的捕获阶段被调用还是冒泡阶段被调用,默认true为捕获阶段。
移除已注册的事件监听器调用element的removeEventListener即可,参数不变。
element.removeEventListener(‘click’, observer,useCapture);
直接在DOM节点上加事件
如何取消浏览器事件的传递与事件传递后浏览器的默认处理:
取消事件传递是指,停止捕获型事件或冒泡型事件的进一步传递。例如上图中的冒泡型事件传递中,在body处理停止事件传递后,位于上层的document的事件监听器就不再收到通知,不再被处理。
事件传递后的默认处理是指,通常浏览器在事件传递并处理完后会执行与该事件关联的默认动作(如果存在这样的动作)。
取消浏览器的事件传递:
在IE下,通过设置event对象的cancelBubble为true即可。
functionsomeHandle() {
window.event.cancelBubble = true;
}
DOM标准通过调用event对象的stopPropagation()方法即可。
functionsomeHandle(event) {
event.stopPropagation();
}
因此,跨浏览器的停止事件传递的方法是:
functionsomeHandle(event) {
event = event || window.event;
if(event.stopPropagation)
event.stopPropagation();
else event.cancelBubble = true;
}
取消事件传递后的默认处理
在IE下,通过设置event对象的returnValue为false即可。
functionsomeHandle() {
window.event.returnValue = false;
}
DOM标准通过调用event对象的preventDefault()方法即可。
functionsomeHandle(event) {
event.preventDefault();
}
因此,跨浏览器的取消事件传递后的默认处理方法是:
functionsomeHandle(event) {
event = event || window.event;
if(event.preventDefault)
event.preventDefault();
else event.returnValue = false;
}
可见,为了兼容不同浏览器的不同标准,我们需要添加多一些if..else判断才能在各种浏览器上跑起来。生活中,人也是这样,每个人的性格不同,需要我们多一些包容,胸怀才能更广阔,才能与人更好地相处。
Author:致知
Sign:路漫漫其修远兮,吾将上下而求索。
原文地址:http://blog.csdn.net/lzgs_4/article/details/46224561