在Dom Level1中没有定义事件模型,在Dom Level2中定义了事件模型一个较小的子集,在Dom Level3(2004)中事件才被完整定义。
        由于IE还没有对于Dom Level1的完整支持,所以当前的浏览器主要存在IE和DOM两种不同的事件模型。这直接导致了事件处理成为JS跨浏览器编程中差异最大的部分。还好除 了IE之外,Mozilla FireFox、Opera、Safari都统一实现了Dom Level2定义的事件模型。
        本文尝试总结关于事件处理的所有相关要点,包括添加删除事件、得到事件对象、得到触发事件的对象、捕获和冒泡事件流、终止事件流、阻止某个事件的默认行为等等。

一、添加事件的方式
1.写在HTML元素标签内:
<div onclick="clk()" >testSrc</div></div>这样,你甚至可以不去理会event对象,而事件处 理函数传入的this即是指向outerDiv的指针。
        当然这只是针对第1种添加事件的方法而言,而针对不可以传入参数的第2,3种添加事件方法则没有什么好办法,一直向上查找parentNode直到找到为止吧。

这里可以看出三种添加事件的方法是各有短长的,根据实际情况来选择应用吧。

四、事件对象还包含哪些信息
这块儿的东西我最不喜欢写,东西挺多浏览器差异大我记住的很少。
把我用比较多的列出来,而且基本上这些各个浏览器是一致的。
oEvent.type 事件类型 click、mouseover等等
oEvent.clientX oEvent.clientY 鼠标事件触发的坐标(相对于浏览器窗口)
oEvent.screenX oEvent.screenY 鼠标时间触发的坐标(相对于屏幕)
oEvent.keyCode 键盘事件按键代码
oEvent.altKey oEvent.ctrlKey oEvent.shiftKey 事件发生时alt、ctrl、shift键是否按下

 如果您想全面了解事件一共有多少种,每种是做什么的,每个事件内部包含哪些对象,请查看帮助手册或者这位仁兄的文章

五、事件流
  只有事件是不够的,一个点击触发的事件有多个,当你点击了一个链接,相当于同时点击了他所在的div,也相当于点击了整个body。
  事件流即各个事件触发的顺序,这又是IE和Dom有着很大差异的地方。
从一个测试页面开始吧:

 

关于跨浏览器事件(EVENT)<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN' 'http://www.w3.org/TR/html4/strict.dtd'>
<html>
<head>
</SCRIPT>
  </head>
关于跨浏览器事件(EVENT)
<body onload="bol()">
关于跨浏览器事件(EVENT)    
<div id="do" class=bd>
关于跨浏览器事件(EVENT)        
<div id="dm">
关于跨浏览器事件(EVENT)            
<div id="di" class=bd style="margin:50px">
关于跨浏览器事件(EVENT)                aa
关于跨浏览器事件(EVENT)            
</div>
关于跨浏览器事件(EVENT)        
</div>
关于跨浏览器事件(EVENT)    
</div>
关于跨浏览器事件(EVENT)
</body>
关于跨浏览器事件(EVENT)
</html>

  

 

  对于IE事件的触发是自下而上单向的冒泡型的事件流,页面里先触发di->dm->do->...
  对于Dom的事件模型是自上而下有自下而上的称为捕获型的事件流,页面里触发顺序为...->do->dm->di->(txt)->(txt)->di->dm->do...
  Dom 事件模型中事件可以定义在捕获阶段也可以定义在冒泡阶段,这个就是由addEventListener方法的第三个参数决定的,true代表在捕获阶段触 发,false代表在冒泡阶段触发。大家可以尝试把页面的addEventListener方法第三个参数改成true看下ie和firefox的不同效 果。
  需要强调的是Dom事件模型中只有前面提到的第三种添加事件的方法可以增删捕获阶段事件处理函数,前两种方法都默认指定冒泡阶段的事件, 所以大家在之前开发中很少会注意到这些差异。而且既然IE没有支持,基本上没有存在只支持Firefox网页的必要,所以捕获阶段的事件只能说看上去不 错。

从这个测试页面我们还可以得到几点结论:
1.id==dm的div,在页面上并没有展现,边框都没,但是点击他的子节点仍然会触发他的onclick事件。
2.addEvent方法是一个简易的去除增删事件处理函数差异的方法,我们可以开发一些服务方法来统一事件处理。
3. 事件流的描述中我使用了"...",代表继续向上或向下触发的元素事件,这个也是比较麻烦的地方,IE的不同版本都不同,有div->body- >document的还有div->html->body->document的,只要记住不要给html元素添加事件处理函数 就好了。

六、停止事件流
事件流存在,势必需要一种方式能够让事件流打住,阻止继续冒泡。
在IE中:oEvent.cancelBubble = true;
在Dom中:oEvent.stopPropagation();
把上面的测试页注掉的代码打开就可以看到效果

七、阻止事件默认动作
  一个动作的触发事件的同时往往带有其目的,比如按键代表输入字符,点击链接代表去链接的地址等等。
  事件发生在这些默认动作执行前,希望检查只有满足一定要求才进行默认动作,这需要一种方式能够阻止事件默认动作。
有两种方式
第1种写在JS中
对于IE:oEvent.returnValue=false;
对于Dom:oEvent.preventDefault();
第2种方式针对前面介绍的第1种添加事件的方式:
<a href="
http://yahoo.cn" onclick="return clk()">yahoo</a>
<script>
function clk(){
 if(Math.random()>0.5){
  return false;
 }else{
  return true;
 }
}
</script>
在事件处理函数调用前加了return,而根据事件处理函数return值来决定是否进行默认动作。

另外,很多网页这么写onclick="javascript:clk()";这样的做没有必要,因为不支持js的浏览器同样不会认,支持js的浏览器不用写也一样。想来可能和vbscript有关吧,谁非要在一个页面用两种script呢。

八、JS模拟点击
IE下面:
oDiv=document.getElementById("testDiv");
oDiv.click();

 原文地址 http://blog.csdn.net/lenel

相关文章: