javascript系列之DOM(三)---事件

    事件是javascript跳动的心脏,是DOM所有成分结合的万金油。当我们在WEB 上进行某些交互时,事件也就发生了。点击某些内容,鼠标经过特定元素,按下某些按键,改变窗口。当然还可能是浏览器上某个页面加载完毕。通过 javascript你可以监听特定事件的发生,为事件绑定处理函数。

DOM事件流

    在DOM中,当某一个特定的HTNL元素产生事件时,该事件会在该元素节点与根节点之间按特定的顺序传播,所经过的节点都会监听到该事件(但不一定执行该 事件对应的动作,因为未绑定事件处理函数),这个传播过程就是DOM事件流。事件流有两种事件顺序:事件捕获和事件冒泡。

冒泡型事件(event bubble):冒泡型事件最早由IE实现,事件就像水中的气泡,有目标元素逐级向上冒,直到顶端的根节点

捕获型事件(event capture):捕获型事件有netscape实现,它与冒泡刚好相反,事件从根节点逐级派送到目标元素。

DOM标准事件模型:W3C这个红娘将二者融合在一起就形成了DOM标准事件模型。先执行捕获,然后再冒泡(所以,若果一个处理函数既被绑定了捕获型事件,又被绑定了冒泡型事件,那么这个事件处理函数会执行两次,而且先执行捕获型事件)。

event-buddledomevent 

事件监听器和事件处理函数

     事件处理函数(有的地方叫做事件句柄,此称谓容易和事件监听器混淆,个人不推荐),用于响应某个事件而调用的函数。每一个事件都应该对应一个事件处理函数 (理论上),否则就是做无用功,浪费资源。事件发生时,浏览器执行对应的事件处理函数,从而实现页面内容和用户操作的交互。我们认为响应点击事件的处理函 数为onclick。事件处理函数的两种分配方式:javascript和html(内联的事件处理函数方式早已经过去,不再讨论)中。如果在 javascript中分配事件处理函数,首先需要获得处理对象的引用,然后将函数绑定到对象的事件处理函数属性上:

1  var link=document.getElementById("mylink");
2  link.onclick=function(){
3   alert("I was clicked !");
4 }; 

    这种分配事件处理函数的特定是简单,但不能为同一事件绑定多个事件处理函数。鉴于此缺点,现在大多数浏览器内置了事件监听器来更全面的绑定事件处理函数。 在IE下的事件监听器是attachEvent(),W3C标准型的事件监听器是addeventListener()。

A:attachEvent()

   在IE下,每个元素和window对象都有两个方法attachEvent和detachEvent方法。

element.attachEvent("onevent",eventListener);第一个参数是事件类型名,第二个参数是事件处理函 数。在IE下处理函数调用时this指向的不再是先前注册事件的元素,而是window(window.event的使用)。还有一点就是事件前面要 加"on"。 element.attachEvent("onevent",eventListener)删除事件监听器,参数一致。

B:addEventListener()

    在支持W3C标准事件监听器的浏览器,每个对象都可以使用addEventListener方法。该方法及支持冒泡型事件处理,也支持捕获型事件处理。 elem.addEventListener(type,eventListener,capture),默认情况下capture取false,即为冒 泡型事件处理。addEventListener方法接受三个参数。第一个是事件类型,不需要加"on",第二个是事件处理函数,第三个是决定事件处理函 数在冒泡还是捕获阶段调用。移除事件已经注册的监听器用removeEventListener。 和注册的时候参数一致element.removeEventListener('event', eventListener, useCapture);

跨浏览器的事件监听器

     既然IE和W3C注册时间监听器的方案是不同的,对于支持addEventListener方法的浏览器,只要需要事件监听器脚本就都需要调用addEventListener方法;而对于不支持该方法的IE浏览器,使用事件监听器时则需要调用attachEvent方法。那么我们要兼容浏览器也不是什么困难的事,下面是具体的兼容浏览器的注册事件监听器方案:

 1 var eventUtil={
 2     //注册
 3     addHandler:function(elem,type,handler){
 4         if(elem.addEventListener){
 5             elem.addEventListener(type,handler,false);
 6         }else if(elem.attachEvent){
 7             elem.attachEvent("on"+type,handler);
 8         }else{
 9             elem["on"+type]=handler;
10         }
11     }
12     //移除
13     removehandler:function(elem,type,handler){
14         if(elem.removeListener){
15             elem.removeListener(type,handler,false)
16         }else if(elem.detachEvent){
17             elem.detachEvent("on"+type,handler)
18         }else{
19             elem["on"+type]=null;
20         }
21     }
22 }

    当事件发生的时候触发事件处理函数,W3C情况下,event对象将自动在事件处理函数内可用,这个对象包含了该事件的全部信息。但在IE下是通过全局对象window下的event属性来包含这些信息的。跨浏览器在获取事件对象和事件目标:

 1 var eventUtil={
 2     handler:function(event){
 3         event=event||window.event
 4         do somesthing
 5     }
 6     getTarget;function(event){
 7         return event,target||event.srcElement
 8 
 9     }
10 }
阻止事件默认行为和阻止事件冒泡

     阻止事件冒泡,停止冒泡型事件的进一步传递(取消事件传递不只是停止IE和DOM标准共有的冒泡型事件,我们还可以停止支持DOM标准浏览器的捕捉型事件,用stopPropagation()方法。

    阻止事件的默认行为,通常浏览器在事件处理完后会执行与该事件关联的默认操作。例如,如果表单中input type 属性是 “submit”,点击后在事件传播完浏览器就自动提交表单。又例如,input 元素的 keydown 事件发生并处理后,浏览器默认会将用户键入的字符自动追加到 input 元素的值中。

A:停止事件冒泡的处理方法(把此函数放在目标元素处理函数的最后一行):

1 function stopHandle(event){
2     event=event||window.event
3     if(event.stopPropagation){
4         event.stopPropagation();
5     }else{
6         event.cancelBubble=true;
7     }    
9 }

B:阻止事件的默认行为

1 function defaultHandle(event){
2     event=event||window.event
3     if(event.preventDefault){
4         event.preventDefault();
5     }else{
6         event.returnValue=false;
7     }    
9 }
 事件委托

    事件委托是建立在事件冒泡的基础上的,有这么一个例子,如果你有一个多行的表格,在每个<tr>上绑定点击事件是个非常影响性能的大问题。大 多数库或者框架的做法是使用事件委托。事件委托将事件绑定在包含目标元素的容器元素上,然后通过判断点击的目标子元素来触发相应的事件。

1 var myTable=dcument.getElementById("tab");
2 myTable.addEventListener(click,function(event){
3     event=event||window.event;
4     var targetNode=event.target||event.srcElement
5     if(targetNode.nodeName.toLowerCase()=="tr"){
6         alert("you have clicked");
7     }
8 })
posted @ 2014-05-05 21:11  明娃儿  阅读(905)  评论(0编辑  收藏  举报