事件句柄和事件接听器

 

我们认为响应点击事件的函数是onclick事件处理函数。以前,事件处理函数有两种分配方式:在JavaScript中或者在HTML中

如果在JavaScript 中分配事件处理函数, 则需要首先获得要处理的对象的一引用,然后将函数赋值给对应的事件处理函数属性,请看一个简单的例子:

 

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

 

从我们看到的例子中,我们发现使用事件句柄很容易, 不过事件处理函数名称必须是小写的,还有就是只有在 元素载入完成之后才能将事件句柄赋给元素,不然会有异常。

关于文档载入技术,请看《window.onload加载的多种解决方案》 的文章。

如果在HTML中分配事件句柄的话,则直接通过HTML属性来设置事件处理函数就行了,并在其中包含合适的脚本作为特性值就可以了,例如:

<a href="/" onclick="JavaScript code here">......</a>

这种JavaScript 代码和通过HTML的style属性直接将CSS属性赋给元素类似。这样会代码看起来一团糟,也违背了将实现动态行为的代码与显示文档静态内容的代码相分离的原则。从1998年开始,这种写法就过时了。

这种传统的事件绑定技术,优缺点是显然的:

*简单方便,在HTML中直接书写处理函数的代码块,在JS中给元素对应事件属性赋值即可。

*IE与DOM标准都支持的一种方法,它在IE与DOM标准中都是在事件冒泡过程中被调用的。

*可以在处理函数块内直接用this引用注册事件的元素,this引用的是当前元素。

*要给元素注册多个监听器,就不能用这方法了。

事件接听器

除了前面已经介绍的简单事件句柄之外,现在大多数浏览器都内置了一些更高级的事件处理方式,即,事件监听器,这种处理方式就不受一个元素只能绑定一个事件句柄的限制。

我们已经知道了事件句柄与事件监听器的最大不同之处是使用事件句柄时一次只能插接一个事件句柄,但对于事件监听器,一次可以插接多个。

IE下的事件监听器:

IE提供的却是一种自有的,完全不同的甚至存在BUG的事件监听器,因此如果要让脚本在本浏览器中正常运行的话,就必须使用IE所支持的事件监听器。另外,Safari 浏览器中的事件监听器有时也存在一点不同。

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

element.attachEvent("onevent",eventListener);

此方法的意思是在IE中要想给一个元素的事件附加事件处理函数,必须调用attachEvent方法才能创建一个事件监听器。attachEvent方法允许外界注册该元素多个事件监听器。

attachEvent接受两个参数。第一个参数是事件类型名,第二个参数eventListener是回调处理函数。这里得说明一下,有个经常会出错的地方,IE下 利用attachEvent注册的处理函数调用时this指向不再是先前注册事件的元素,这时的this为window对象。还有一点是此方法的事件类型名称必须加上一个”on”的前缀(如onclick)。

element.attachEvent("onevent",eventListener);

要想移除先前元素注册的事件监听器,可以使用detachEvent方法进行删除,参数相同。

DOM标准下的事件监听器:

在支持W3C标准事件监听器的浏览器中,对每个支持事件的对象都可以使用addEventListener方法。该方法既支持注册冒泡型事件处理,又支持捕获型事件处理。所以与IE浏览器中注册元素事件监听器方式有所不同的。

//标准语法  element.addEventListener('event', eventListener, useCapture); //默认 element.addEventListener('event', eventListener, false);

addEventListener方法接受三个参数。第一个参数是事件类型名,值得注意的是,这里事件类型名称与IE的不同,事件类型名是没’on’开头的;第二个参数eventListener是回调处理函数(即监听器函数);第三个参数注明该处理回调函数是在事件传递过程中的捕获阶段被调用还是冒泡阶段被调用 ,通常此参数通常会设置为false(为false时是冒泡),那么,如果将其值设置为true,那就创建一个捕捉事件监听器。

移除已注册的事件监听器调用element的removeEventListener方法即可,参数相同。

//标准语法  element.removeEventListener('event', eventListener, useCapture); //默认 element.removeEventListener('event', eventListener, false);

通过addEventListener方法添加的事件处理函数,必须使用removeEventListener方法才能删除,而且要求参数与添加事件处理函数时addEventListener方法的参数完全一致(包括useCapture参数),否则将不能成功删除事件处理函数。

跨浏览器的注册与移除元素事件监听器方案

我们现在已经知道,对于支持addEventListener方法的浏览器,只要需要事件监听器脚本就都需要调用addEventListener方法;而对于不支持该方法的IE浏览器,使用事件监听器时则需要调用attachEvent方法。要确保浏览器使用正确的方法其实并不困难,只需要通过一个if-else语句来检测当前浏览器中是否存在addEventListener方法或attachEvent方法即可。

这样的方式就可以实现一个跨浏览器的注册与移除元素事件监听器方案:

 

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

 

事件对象引用

为了更好的处理事件,你可以根据所发生的事件的特定属性来采取不同的操作。

如事件模型一样,IE 和其他浏览器处理方法不同:IE 使用一个叫做 event 的全局事件对象来处理对象(它可以在全局变量window.event中找到),而其它所有浏览器采用的 W3C 推荐的方式,则使用独立的包含事件对象的参数传递。

跨浏览器实现这样的功能时,最常见的问题就是获取事件本身的引用及获取该事件的目标元素的引用。

下面这段代码就为你解决了这个问题:

复制代码
var EventUtil ={   getEvent: function(event){     return event ? event : window.event;   },   getTarget: function(event){     return event.target || event.srcElement;   } };
复制代码
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
 <head>
  <title> New Document </title>
  <meta charset="UTF-8">
    <style>
        #mylink {
            background: #ff0000
        }
    </style>
 </head>
 <body>
 <div id="mylink" > Click Me (javascript注册事件) </div>
 <hr>
 Html 注册事件:
 <a href="#" onclick="var a=1;var b=2;alert(a+b);">JavaScript code here</a>
<hr>
 <a href="#" onclick="callIt();">callIt</a>
<hr>

<script type="text/javascript">
var link=document.getElementById("mylink");
link.onclick=function(){
  alert("I was clicked !");
};

function callIt(){
  alert("I was called !");
}
</script>
 </body>
</html>

 

posted @ 2017-10-16 15:42  sky20080101  阅读(89)  评论(0)    收藏  举报