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 相关文章推荐
JavaScript 异步调用框架 (Part 2 - 用例设计)
Aug 03 Javascript
JavaScript高级程序设计 阅读笔记(七) ECMAScript中的语句
Feb 27 Javascript
node.js中的fs.appendFileSync方法使用说明
Dec 17 Javascript
jQuery制作简洁的多级联动Select下拉框
Dec 23 Javascript
JavaScript中数据结构与算法(四):串(BF)
Jun 19 Javascript
javascript实现图片延迟加载方法汇总(三种方法)
Aug 27 Javascript
JS实现显示带倒影的图片横排居中放大展示特效实例【测试可用】
Aug 23 Javascript
vue引入swiper插件的使用实例
Jul 19 Javascript
layui的表单验证支持ajax判断用户名是否重复的实例
Sep 06 Javascript
JS中==、===你分清楚了吗
Mar 04 Javascript
使用JavaScript获取Django模板指定键值数据
May 27 Javascript
JavaScript 异步时序问题
Nov 20 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
PHP安全配置
2006/10/09 PHP
BBS(php & mysql)完整版(五)
2006/10/09 PHP
php 连接mysql连接被重置的解决方法
2011/02/15 PHP
PHP实现RTX发送消息提醒的实例代码
2017/01/03 PHP
nodejs 后缀名判断限制代码
2011/03/31 NodeJs
原生javascript兼容性测试实例
2013/07/01 Javascript
使用js如何实现全选与全不选
2013/12/30 Javascript
jQuery监控文本框事件并作相应处理的方法
2015/04/16 Javascript
详解AngularJS中的作用域
2015/06/17 Javascript
Angular路由简单学习
2016/12/26 Javascript
ES6中module模块化开发实例浅析
2017/04/06 Javascript
Express的HTTP重定向到HTTPS的方法
2018/06/06 Javascript
vue-cli的工程模板与构建工具详解
2018/09/27 Javascript
使用Vue.observable()进行状态管理的实例代码详解
2019/05/26 Javascript
vuex实现数据状态持久化
2019/11/11 Javascript
Python脚本简单实现打开默认浏览器登录人人和打开QQ的方法
2016/04/12 Python
Python基础语言学习笔记总结(精华)
2017/11/14 Python
Python快速转换numpy数组中Nan和Inf的方法实例说明
2019/02/21 Python
PyTorch的torch.cat用法
2020/06/28 Python
Python通用唯一标识符uuid模块使用案例
2020/09/10 Python
浅析HTML5中的download属性使用
2019/03/13 HTML / CSS
Lungolivigno Fashion官网:高级时装在线购物
2020/10/17 全球购物
新驾驶员个人自我评价
2014/01/03 职场文书
座谈会主持词
2014/03/20 职场文书
社区工作者演讲稿
2014/05/23 职场文书
小学亲子活动总结
2014/07/01 职场文书
学习党的群众路线对照检查材料
2014/09/29 职场文书
机关作风整顿个人整改措施思想汇报
2014/09/29 职场文书
警察群众路线对照检查材料思想汇报
2014/10/01 职场文书
2014党员整改措施思想汇报
2014/10/07 职场文书
2015年纪检监察工作总结
2015/04/08 职场文书
暑期家教宣传单
2015/07/14 职场文书
小学生组织委员竞选稿
2015/11/21 职场文书
Windows中Redis安装配置流程并实现远程访问功能
2021/06/07 Redis
php 文件上传至OSS及删除远程阿里云OSS文件
2021/07/04 PHP
java实现自定义时钟并实现走时功能
2022/06/21 Java/Android