JavaScript中为事件指定处理程序的五种方式分析


Posted in Javascript onJuly 27, 2018

本文实例讲述了JavaScript中为事件指定处理程序的五种方式。分享给大家供大家参考,具体如下:

JavaScript和HTML之间的交互是通过事件实现的。

IE9、Firefox、Opera、Sarifi、Chrome都已经实现了DOM2级事件模块的核心部分,IE8是最后一个仍然使用其专有事件系统的主要浏览器。

事件流:

事件流描述的是从页面中接受事件的顺序,但IE和Netscape却提出了完全相反的事件流的概念,IE的事件流是事件冒泡流,而Netscape的事件流是事件捕获流。

1) 事件冒泡

事件开始时由最具体的元素(文档中嵌套层次最深的那个节点接收,然后逐级向上传播到较为不具体的节点(文档)。

不支持事件冒泡的事件:blurfocusloadunload

2) 事件捕获

不太具体的节点应该更早接收到事件,而最具体的节点应该最后接收到事件。事件捕获的用意在于事件到达预定目标之前捕获它。

虽然IE9、Safari、Chrome、Firefox、Opera都支持事件捕获和事件冒泡,但IE8及其更早版本只支持事件冒泡,不支持事件捕获,因此。建议使用事件冒泡,在有特殊需要的时候再使用事件捕获。

DOM事件流:

DOM2级事件规定的事件流包括三个阶段:事件捕获阶段,处于目标阶段和事件冒泡阶段。实际上,在事件捕获阶段预定目标不会接收到事件,处于目标阶段事件在预定目标上发生。事件处理中,处于目标阶段被看成事件冒泡阶段的一部分。但是,即使“DOM2级事件”规范明确要求捕获阶段不会涉及事件目标,但IE9、 Safari、Chrome、Firefox和Opera9.5及更高版本都会在捕获阶段触发事件对象上的事件,结果是有两个机会在目标对象上操作事 件。

IE9、Firefox、Opera、Sarifi、Chrome都支持DOM事件流,IE8及其更早版本不支持DOM事件流。

事件处理程序:

事件就是用户或浏览器自身执行的某种动作,而响应某个事件的函数就是事件处理程序(或事件侦听器),事件处理程序的名字以“on”开头。

JavaScript中有五种事件处理程序方式:

1) HTML事件处理程序

每种事件都可以使用一个与相应事件处理程序同名的HTML特性来指定,特性的值可以是能够执行的JavaScript代码,也可以是函数。函数中有一个局部变量event,通过event变量可以访问事件对象;在函数内部,this值等于事件的目标元素。

在HTML中指定事件处理程序的几个缺点:

① 时差问题:用户可能在HTML元素一出现在页面上就触发相应的事件,但当时的事件处理程序有可能尚不具备执行条件,如用户在解析事件处理函数之前就触发事件。为此,很多HTML事件处理程序都会封装在一个try-catch块中,以便及时捕获错误,以免错误抛出被用户看到。

② 扩展事件处理程序的作用域链在不同浏览器中会导致不同的结果。不同JavaScript引擎遵循的标识符解析规则略有差异,很有可能会在访问非限定对象成员时出错。

③ HTML代码与JavaScript代码紧密耦合,更换事件处理程序需要改动HTML代码与JavaScript代码。

2) DOM0级事件处理程序

通过JavaScript指定事件处理程序的传统方式,将一个函数赋值给一个事件处理程序属性。使用DOM0级方法指定的事件处理程序被认为是元素的方法,因此this引用当前元素。

DOM0级事件处理程序的优势:

① 简单;

② 跨浏览器

可以通过将事件处理程序的值设置为null来删除通过DOM0级方法指定的事件处理程序。

3) DOM2级事件处理程序

DOM2级事件定义了两种方法,用于指定和删除事件处理程序的操作:addEventListener()removeEventListener(),它们都接收3个参数:要处理的事件名、作为事件处理程序的函数和一个布尔值(true表示在捕获阶段调用事件处理程序,false表示在冒泡阶段调用事件处理程序)。

DOM2级事件处理程序的优势:

可以添加多个事件处理程序,它们会按照添加它们的顺序触发。

通过addEventListener()添加的事件处理程序只能用removeEventListener()来移除,但要求移除时传入的参数与添加事件处理程序时使用的参数相同,因此通过addEventListener()添加的匿名函数将无法移除,需要给removeEventListener()传入addEventListener()中命名的函数才能正常移除。

4) IE事件处理程序

IE事件定义了两个方法:attachEvent()detachEvent(),它们都接收2个参数:要处理的事件名、作为事件处理程序的函数.由于IE8及其更早版本只支持事件冒泡,所以通过attachEvent()添加的事件处理程序都会被添加到冒泡阶段。

注意:通过IE的attachEvent()添加的事件处理程序的名字以“on”开头,而通过DOM的addEventListener()添加的名字不是。

在IE中使用attachEvent()与使用DOM0级方法的主要区别:

事件处理程序的作用域不同。在IE中使用attachEvent(),事件处理程序会在全局作用域中运行,因此this等于window;而使用DOM0级方法,事件处理程序会在其所属元素的作用域中运行。

在IE中使用attachEvent()与使用DOM2级方法的区别:

添加多个事件处理程序的执行顺序不同。在IE中使用attachEvent(),可以添加多个事件处理程序,它们会按照添加它们的相反顺序触发;在DOM中使用addEventListener(),可以添加多个事件处理程序,但它们会按照添加它们的顺序触发。

通过attachEvent()添加的事件处理程序只能用detachEvent()来移除,但要求移除时传入的参数与添加事件处理程序时使用的参数相同,因此通过attachEvent()添加的匿名函数将无法移除,需要给detachEvent()传入attachEvent()中命名的函数才能正常移除。

5) 跨浏览器的事件处理程序

要保证事件处理程序的代码在大多数浏览器下一致地运行,只需关注冒泡阶段。

视情况分别使用DOM2级方法、IE方法、DOM0级方法来添加和移除事件,addHandler()removeHandler()方法属于EventUtil对象。

① 先检测传入的元素是否存在DOM2级方法(传入的第三个参数为false以表示冒泡阶段);

② 再检测传入的元素是否存在IE的方法;

③ 最后检测传入的元素是否存在DOM0级方法(使用方括号语法将属性名指定为事件处理程序)。

var EventUtil = {
  addHandler:function(element, type, handler) {
    if (element.addEventListener)
      element.addEventListener(type, handler, false);
    else if (element.attachEvent)
      element.attachEvent("on" + type, handler);
    else
      element["on" + type] = handler;
  },
  removeHandler:function(element, type, handler) {
    if (element.removeEventListener)
      element.removeEventListener(type, handler, false);
    else if (element.detachEvent)
      element.detachEvent(“on” + type, handler);
    else
      element["on" + type] = null;
  }
}

PS:关于javascript事件说明可参考本站javascript事件与功能说明大全:http://tools.3water.com/table/javascript_event

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
JQuery Study Notes 学习笔记(一)
Aug 04 Javascript
有趣的JavaScript数组长度问题代码说明
Jan 20 Javascript
精通Javascript系列之数据类型 字符串
Jun 08 Javascript
javascript的解析执行顺序在各个浏览器中的不同
Mar 17 Javascript
jquery实现select选择框内容左右移动代码分享
Nov 21 Javascript
理解Javascript图片预加载
Feb 23 Javascript
移动端H5开发 Turn.js实现很棒的翻书效果
Jun 20 Javascript
浅谈Vue.js中ref ($refs)用法举例总结
Dec 19 Javascript
如何快速解决JS或Jquery ajax异步跨域的问题
Jan 08 jQuery
layui button 按钮弹出提示窗口,确定才进行的方法
Sep 06 Javascript
Vue.directive 实现元素scroll逻辑复用
Nov 29 Javascript
Vue解决echart在element的tab切换时显示不正确问题
Aug 03 Javascript
浅谈Redux中间件的实践
Jul 27 #Javascript
JavaScript多态与封装实例分析
Jul 27 #Javascript
Vue配合iView实现省市二级联动的示例代码
Jul 27 #Javascript
react native 文字轮播的实现示例
Jul 27 #Javascript
Vue render渲染时间戳转时间,时间转时间戳及渲染进度条效果
Jul 27 #Javascript
浅析Vue项目中使用keep-Alive步骤
Jul 27 #Javascript
在vue中使用Autoprefixed的方法
Jul 27 #Javascript
You might like
Cakephp 执行主要流程
2010/03/24 PHP
thinkphp中html:list标签传递多个参数实例
2014/10/30 PHP
Yii2学习笔记之汉化yii设置表单的描述(属性标签attributeLabels)
2017/02/07 PHP
php自定义函数br2nl实现将html中br换行符转换为文本输入中换行符的方法【与函数nl2br功能相反】
2017/02/17 PHP
超级兔子让浮动层消失的前因后果
2007/03/09 Javascript
js字符串的各种格式的转换 ToString,Format
2011/08/08 Javascript
jQuery使用removeClass方法删除元素指定Class的方法
2015/03/26 Javascript
封装属于自己的JS组件
2016/01/27 Javascript
vue.js学习之递归组件
2016/12/13 Javascript
有关JS中的0,null,undefined,[],{},'''''''',false之间的关系
2017/02/14 Javascript
解析jquery easyui tree异步加载子节点问题
2017/03/08 Javascript
vue.js实现含搜索的多种复选框(附源码)
2017/03/23 Javascript
VUE使用vuex解决模块间传值问题的方法
2017/06/01 Javascript
three.js中3D视野的缩放实现代码
2017/11/16 Javascript
Element Table的row-class-name无效与动态高亮显示选中行背景色
2018/11/30 Javascript
Vue项目总结之webpack常规打包优化方案
2019/06/06 Javascript
js实现图片上传到服务器和回显
2020/01/19 Javascript
JS实现的定时器展示简单秒表、页面弹框及跳转操作完整示例
2020/01/26 Javascript
vue 函数调用加括号与不加括号的区别
2020/10/29 Javascript
[46:04]Liquid vs VP Supermajor决赛 BO 第四场 6.10
2018/07/05 DOTA
[01:36]极致酷炫!TI9典藏宝瓶+撼地者至宝展示
2019/06/11 DOTA
Python实现简单的代理服务器
2015/07/25 Python
深入解析Python中的urllib2模块
2015/11/13 Python
python获取list下标及其值的简单方法
2016/09/12 Python
python实现翻转棋游戏(othello)
2019/07/29 Python
Pytorch加载部分预训练模型的参数实例
2019/08/18 Python
python处理写入数据代码讲解
2020/10/22 Python
24个canvas基础知识小结
2014/12/17 HTML / CSS
财政专业求职信范文
2014/02/19 职场文书
央视元宵晚会主持串词
2014/03/25 职场文书
特教教师先进事迹
2014/05/21 职场文书
金融专业求职信
2014/08/05 职场文书
2015年毕业生自我鉴定模板
2014/09/19 职场文书
合伙经营协议书范本(通用版)
2014/12/03 职场文书
浅谈Redis在直播场景的实践方案
2021/04/27 Redis
Python OpenCV实现图形检测示例详解
2022/04/08 Python