浅谈Javascript事件处理程序的几种方式


Posted in Javascript onJune 27, 2012

事件就是用户或浏览器自身执行的某种动作。比如说click,mouseover,都是事件的名字。而相应某个事件的函数就叫事件处理程序(或事件侦听器)。为事件指定处理程序的方式有好几种。
一:HTML事件处理程序。
如:

<script type="text/javascript"> 
function show(){ 
alert('hello world!'); 
} 
</script> 
<input type="button" value="click me" onclick="show()"/>

相信这种方式是目前咱们大家用得比较多的一种,但是在html中指定事件处理程序有两个缺点。
(1)首先:存在一个时差问题。就本例子来说,假设show()函数是在按钮下方,页面的最底部定义的,如果用户在页面解析show()函数之前就单击了按钮,就会引发错误;
(2)第二个缺点是html与javascript代码紧密耦合。如果要更换时间处理程序,就要改动两个地方:html代码和javascript代码。
因此,许多开发人员摒弃html事件处理程序,转而使用javascript指定事件处理程序。
二:Javascript指定事件处理程序
javascript指定事件处理程序包括三种方式:
(1):DOM0级事件处理程序
如:
var btn=document.getElementById("mybtn"); //取得该按钮的引用 
btn.onclick=function(){ 
alert('clicked'); 
alert(this.id); // mybtn

以这种方式添加的事件处理程序会在事件流的冒泡阶段被处理。
删除DOM0级方法指定的事件处理程序:
btn.onclick=null; // 删除事件处理程序
}
(2):DOM2级事件处理程序
DOM2级事件定义了两个方法,用于处理指定和删除事件处理程序的操作:addEventListener()和removeEventListener()。所有DOM节点中都包含这两个方法,并且它们都接受3个参数:要处理的事件名,做为事件处理程序的函数和一个布尔值。最后这个参数如果是true,表示在捕获阶段调用事件处理程序;如果是fasle,表示在冒泡阶段调用事件处理程序。
如:
var btn=document.getElementById("mybtn"); 
btn.addEventListener("click",function(){ 
alert(this.id); 
},false);

使用DOM2级事件处理程序的主要好处是可以添加多个事件处理程序。
如:
var btn=document.getElementById("mybtn"); 
btn.addEventListener("click",function(){ 
alert(this.id); 
},false); 
btn.addEventListener("click",function(){ 
alert("hello world!"); 
},false);

这里为按钮添加了两个事件处理程序。这两个事件处理程序会按照它们的顺序触发。
通过addEventListener()添加的时间处理程序只能使用removeEventListener()来移除,移除时传入的参数与添加时使用的参数相同。这也意味着通过addEventListener()添加的匿名函数将无法移除。
如:
var btn=document.getElementById("mybtn"); 
btn.addEventListener("click",function(){ 
alert(this.id); 
},false); 
//移除 
btn.removeEventListener("click",function(){ //这样写没有用 (因为胃第二次与第一次相比是一个完全不同的函数) 
alert(this.id); 
},false);

解决办法:
var btn=document.getElementById("mybtn"); 
var hander=function(){ 
alert(this.id); 
}; 
btn.addEventListener("click",hander,false); btn.removeEventListener("click",hander,false); // 有效

注意:这里我们的第三个参数都是false,是在冒泡阶段添加的。大多数情况下,都是就事件处理程序添加到事件流的冒泡阶段,这样可以最大限度的兼容各种浏览器。
三:IE事件处理程序
IE实现了与DOM中类似的两个方法:attachEvent()和detachEvent()。这两个方法接受相同的两个参数:事件处理程序名称和事件处理程序函数。由于IE只支持时间冒泡,所有通过attachEvent()添加的事件处理程序都会被添加包冒泡阶段。
如:

三:

var btn=document.getElementById("mybtn"); 
btn.attachEvent("onclick",function(){ 
alert("clicked"); 
})

注意:attachEvent()函数的第一个参数是"onclick",而非DOM的addEventListener()中的"click"。
attachEvent()方法也可以用来为一个元素添加多个事件处理程序。
如:
var btn=document.getElementById("mybtn"); 
btn.attachEvent("onclick",function(){ 
alert("clicked"); 
}); 
btn.attachEvent("onclick",function(){ 
alert("hello world!"); 
});

这里调用了两次attachEvent(),为同一个按钮添加了两个不同的事件处理程序。不过,与DOM方法不同的是,这些事件处理程序不是以它们的添加顺序执行,而是以相反的顺序被触发。单击这个例子中的按钮:首先看到的是"hello world",然后才是"clicked".
使用attachEvent()添加的事件可以通过detachEvent()来移除,条件是必须提供相同的参数。
var btn=document.getElementById("mybtn"); 
var hander=function(){ 
alert("clicked"); 
} 
btn.detachEvent("onclick",hander}); // 移除

以上三种方式为目前的主要的事件处理程序方式,那看到这里你肯定会想到,既然不同的浏览器会有不同的差异,那怎么保证跨浏览器的事件处理程序呢?
为了以跨浏览器的方式处理事件,不少的开发人员是使用能够隔离浏览器差异性的Javascript库,还有一些开发人员会自己开发最合适的事件处理方法。
这里提供一个EventUtil对象,可以用这个对象来处理浏览期间的差异:
var EventUtil = { 
addHandler: function(element, type, handler){ // 该方法接受3个参数:要操作的元素,事件名称和事件处理程序函数 
if (element.addEventListener){ //检查传入的元素是否存在DOM2级方法 
element.addEventListener(type, handler, false); // 若存在,则使用该方法 
} else if (element.addEvent){ // 如果存在的是IE的方法 
element.attachEvent("on" + type, handler); //则使用IE的方法,注意,这里的事件类型必须加上"on"前缀。 
} else { // 最后一种可能是使用DOM0级 
element["on" + type] = hander; 
} 
}, removeHandler: function(element, type, handler){ // 该方法是删除之前添加的事件处理程序 
if (element.removeEventListener){ //检查传入的元素是否存在DOM2级方法 
element.removeEventListener(type, handler, false); // 若存在,则使用该方法 
} else if (element.detachEvent){ // 如果存在的是IE的方法 
element.detachEvent("on" + type, handler); //则使用IE的方法,注意,这里的事件类型必须加上"on"前缀。 
} else { // 最后一种可能是使用DOM0及方法(在现代浏览器中,应该不会执行这里的代码) 
element["on" + type] = null; 
} 
} 
};

可以像下面这样使用EventUtil对象:
var btn =document.getElementById("mybtn"); 
var hander= function(){ 
alert("clicked"); 
}; 
//这里省略了部分代码 
EventUtil.addHandler(btn,"click",hander); 
//这里省略了部分代码 
EventUtil.removeHandler(btn,"click",hander); //移除之前添加的事件处理程序

可见,使用addHandler和removeHandler来添加和移除事件处理程序还是很方便的。
Javascript 相关文章推荐
javascript基础的动画教程,直观易懂
Jan 10 Javascript
JS解密入门之凭直觉解
Jun 25 Javascript
javascript面向对象入门基础详细介绍
Sep 05 Javascript
JQuery的$和其它JS发生冲突的快速解决方法
Jan 24 Javascript
JS创建自定义表格具体实现
Feb 11 Javascript
使用百度地图api实现根据地址查询经纬度
Dec 11 Javascript
node.js中的require使用详解
Dec 15 Javascript
JS简单实现DIV相对于浏览器固定位置不变的方法
Jun 17 Javascript
js + css实现标签内容切换功能(实例讲解)
Oct 09 Javascript
JavaScript实现正则去除a标签并保留内容的方法【测试可用】
Jul 18 Javascript
简单学习5种处理Vue.js异常的方法
Jun 17 Javascript
微信小程序 (地址选择1)--选取搜索地点并显示效果
Dec 17 Javascript
javascript 事件处理程序介绍
Jun 27 #Javascript
jquery 获取自定义属性(attr和prop)的实现代码
Jun 27 #Javascript
IE事件对象(The Internet Explorer Event Object)
Jun 27 #Javascript
跨浏览器的事件对象介绍
Jun 27 #Javascript
UI Events 用户界面事件
Jun 27 #Javascript
浅谈Javascript鼠标和滚轮事件
Jun 27 #Javascript
浅谈Javascript事件模拟
Jun 27 #Javascript
You might like
PHP 数组遍历foreach语法结构及实例
2016/06/13 PHP
thinkphp中的url跳转用法分析
2016/07/12 PHP
php 静态属性和静态方法区别详解
2017/04/09 PHP
php 下 html5 XHR2 + FormData + File API 上传文件操作实例分析
2020/02/28 PHP
js实现的仿新浪微博完美的时间组件升级版
2011/12/20 Javascript
jQuery提交表单ajax查询实例代码
2012/10/07 Javascript
你必须知道的Javascript知识点之&quot;this指针&quot;的应用
2013/04/23 Javascript
jquery $.each 和for怎么跳出循环终止本次循环
2013/09/27 Javascript
javascript的回调函数应用示例
2014/02/20 Javascript
基于canvas实现的钟摆效果完整实例
2016/01/26 Javascript
jQuery+PHP+MySQL实现无限级联下拉框效果
2016/02/19 Javascript
JavaScript 闭包详细介绍
2016/09/28 Javascript
js实现截图保存图片功能的代码示例
2017/02/16 Javascript
vue组件实践之可搜索下拉框功能
2018/11/25 Javascript
JS代码检查工具ESLint介绍与使用方法
2020/02/04 Javascript
python 获取文件列表(或是目录例表)
2009/03/25 Python
Python卸载模块的方法汇总
2016/06/07 Python
深入分析python数据挖掘 Json结构分析
2018/04/21 Python
如何通过50行Python代码获取公众号全部文章
2019/07/12 Python
python中JWT用户认证的实现
2020/05/18 Python
Python3 pywin32模块安装的详细步骤
2020/05/26 Python
Pandas对DataFrame单列/多列进行运算(map, apply, transform, agg)
2020/06/14 Python
详解Python高阶函数
2020/08/15 Python
python 中 .py文件 转 .pyd文件的操作
2021/03/04 Python
Canvas 文字碰撞检测并抽稀的方法
2019/05/27 HTML / CSS
S’well Bottle保温杯官网:绝缘不锈钢水瓶
2018/05/09 全球购物
Linux常见面试题
2016/10/04 面试题
int和Integer有什么区别
2013/05/25 面试题
实习自我鉴定范文
2013/10/30 职场文书
酒店前厅员工辞职信
2014/01/08 职场文书
工程专业求职自荐书范文
2014/02/08 职场文书
省文明单位申报材料
2014/05/08 职场文书
2015年基层党组织公开承诺书
2015/01/21 职场文书
用Python提取PDF表格的方法
2021/04/11 Python
Python基础之教你怎么在M1系统上使用pandas
2021/05/08 Python
win10此电脑打不开怎么办 win10双击此电脑无响应的解决办法
2022/07/23 数码科技