详解JavaScript中的事件流和事件处理程序


Posted in Javascript onMay 20, 2016

事件流:分两种,IE的是 事件冒泡流 ,事件开始时从最具体的元素接收,逐级向上传播到较为不具体的节点(Element -> Document)。与之相反的是 Netscape 的 事件捕获流 。

DOM2级事件规定事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段。

大多数情况下都是将事件处理程序添加到事件流的冒泡阶段。一个 EventUtil 的栗子:

var EventUtil = {
  addHandler: function(element, type, handler){
    if(element.addEventListener){
      element.addEventListener(type, handler, false);
    }else if(element.attachEvent){
      element.attachEvent('on' + type, handler); // IE8
    }else{
      element['on' + type] = handler;
    }
  },
  removeHandler: function(){...}
}

下面我们详细来看:

DOM0级事件处理程序
通过Javascript指定事件处理程序的传统方式,就是将一个函数赋值给一个事件处理程序属性。
每个元素都有自己的事件处理程序属性,这些属性通常全部小写,例如onclick。将这种属性的值设置为一个函数,就可以指定事件处理程序。

var btn = document.getElementById('myBtn');
// 添加事件处理程序
btn.onclick = function () {
  alert( this );//为DOM元素btn
};
// 移除事件处理程序
btn.onclick = null;

优点:1.简单2.具有跨浏览器的优势
缺点:在代码运行之前不会指定事件处理程序,因此这些代码在页面中位于按钮后面,就有可能在一段时间怎么点击都没反应,用户体验变差。

DOM2级事件处理程序
定义了两个方法,用于处理指定和删除事件处理程序的操作:addEventListener()和removeEventListener()。三个参数,1.要处理的事件名。2.作为事件处理程序的函数3.一个布尔值。最后这个布尔值为true,表示在捕获阶段调用事件处理程序,false表示在冒泡阶段调用事件处理程序。

// 添加多个事件处理程序
var btn = document.getElementById('myBtn');
btn.addEventListener('click',function (){
  alert( this );// 为DOM元素btn
},false );
btn.addEventListener('click',function () {
  alert('Hello World');
},false);

// 移除事件处理程序
btn.removeEventListener('click',function () {
  // 匿名函数无法被移除,移除失败
},false);
  // 改写
  var handler = function () {
  alert(this.id);
  };
  btn.addEventListener('click',handler,false);
  // 再次移除事件处理程序
  btn.removeEventListener('click',handler,false);// 移除成功

这两个事件处理程序会按照添加他们的顺序触发。大多数情况,都是将事件处理程序添加到事件流的冒泡阶段,这样可以最大限度的兼容各种版本的浏览器。

优点: 一个元素可以添加多个事件处理程序
缺点: IE8及以下浏览器不支持DOM2级事件处理程序。(包括IE8)

IE事件处理程序
定义了两个方法,与上类似:attachEvent(),detachEvent()。这两个方法接收相同的两个参数:事件处理程序名称和事件处理程序函数。由于IE8以及更早版本的浏览器只支持事件冒泡,所以通过detachEvent()添加的事件处理程序会被添加到冒泡阶段。

var btn = document.getElementById('myBtn');
btn.attachEvent('onclick', function(){
  alert( this );// window
});
btn.attachEvent('onclick', funciton(){
  alert("HELLO, WORLD");
});

点击按钮,这两个事件处理程序的触发顺序与上述刚好相反。不是按照添加事件处理程序的顺序触发,刚好相反。

优点:一个元素可以添加多个事件处理程序
缺点:只支持IE。

跨浏览器的事件处理程序

eg:

var EventUtil = {
  addHandler : function ( ele, type, handler ) {
    if ( ele.addEventListener ) {
      ele.addEventListener( type, handler, false );
    } else if ( ele.attachEvent ) {
      ele.attachEvent( 'on' + type, handler );
    } else {
      ele['on' + type] = handler
    }
  },
  removeHandler: function ( ele, type, handler ) {
    if ( ele.removeEventListener ) {
      ele.removeEventListener( type, handler, false );
    } else if ( ele.detachEvent ) {
      ele.detachEvent( 'on' + type, handler );
    } else {
      ele[ 'on' + type ] = null;
    }
  }
}
Javascript 相关文章推荐
javascript-TreeView父子联动效果保持节点状态一致
Aug 12 Javascript
javascript显示选择目录对话框的代码
Nov 10 Javascript
jQuery对象和Javascript对象之间转换的实例代码
Mar 20 Javascript
JavaScript操作Cookie方法实例分析
May 27 Javascript
BOM系列第三篇之定时器应用(时钟、倒计时、秒表和闹钟)
Aug 17 Javascript
如何利用JQuery实现从底部回到顶部的功能
Dec 27 Javascript
在js代码拼接dom对象到页面上去的模板总结(必看)
Feb 14 Javascript
Bootstrap进度条与AJAX后端数据传递结合使用实例详解
Apr 23 Javascript
使用travis-ci如何持续部署node.js应用详解
Jul 30 Javascript
vue transition 在子组件中失效的解决
Nov 12 Javascript
javascript操作元素的常见方法小结
Nov 13 Javascript
Node.js API详解之 os模块用法实例分析
May 06 Javascript
jQuery基础的工厂函数以及定时器的经典实例分析
May 20 #Javascript
JavaScript中的Object对象学习教程
May 20 #Javascript
jQuery基本选择器(实例及表单域value的获取方法)
May 20 #Javascript
jQuery的实例及必知重要的jQuery选择器详解
May 20 #Javascript
深入理解setTimeout函数和setInterval函数
May 20 #Javascript
JavaScript基础教程——入门必看篇
May 20 #Javascript
jQuery选择器及jquery案例详解(必看)
May 20 #Javascript
You might like
php警告Creating default object from empty value 问题的解决方法
2014/04/02 PHP
PHP中危险的file_put_contents函数详解
2017/11/04 PHP
PHP中number_format()函数的用法讲解
2019/04/08 PHP
不安全的常用的js写法
2009/09/15 Javascript
jquery 选项卡效果 新手代码
2011/07/08 Javascript
Javascript面向对象扩展库代码分享
2012/03/27 Javascript
JavaScript/Js脚本处理html元素的自定义属性解析(亲测兼容Firefox与IE)
2013/11/25 Javascript
js中style.display=""无效的解决方法
2014/10/30 Javascript
jQuery多媒体插件jQuery Media Plugin使用详解
2014/12/19 Javascript
最实用的jQuery分页插件
2016/10/09 Javascript
利用Jquery实现几款漂亮实用的时间轴(附示例代码)
2017/02/15 Javascript
vue2.0中click点击当前li实现动态切换class
2017/06/21 Javascript
Vue之Watcher源码解析(2)
2017/07/19 Javascript
基于模板引擎Jade的应用(详解)
2017/12/12 Javascript
详解.vue文件中style标签的几个标识符
2018/07/17 Javascript
获取layer.open弹出层的返回值方法
2018/08/20 Javascript
Node.js中读取TXT文件内容fs.readFile()用法
2018/10/10 Javascript
Vue多组件仓库开发与发布详解
2019/02/28 Javascript
[38:44]DOTA2上海特级锦标赛A组小组赛#2 Secret VS CDEC第二局
2016/02/25 DOTA
[02:36]DOTA2亚洲邀请赛小组赛精彩集锦:奇迹哥卡尔秀翻全场
2017/03/28 DOTA
[43:03]完美世界DOTA2联赛PWL S2 PXG vs Magma 第二场 11.21
2020/11/24 DOTA
使用Python的Flask框架表单插件Flask-WTF实现Web登录验证
2016/07/12 Python
解决pycharm运行时interpreter为空的问题
2018/10/29 Python
浅谈python3发送post请求参数为空的情况
2018/12/28 Python
Python如何执行系统命令
2020/09/23 Python
10款最佳Python开发工具推荐,每一款都是神器
2020/10/15 Python
PyCharm最新激活码PyCharm2020.2.3有效
2020/11/18 Python
沪江旗下的海量优质课程平台:沪江网校
2017/11/07 全球购物
思想汇报范文
2013/11/04 职场文书
校园文化建设方案
2014/02/03 职场文书
党员教师工作决心书
2014/03/13 职场文书
小学校园之星事迹材料
2014/05/16 职场文书
虎兄虎弟观后感
2015/06/12 职场文书
2016年企业安全生产月活动总结
2016/04/06 职场文书
导游词之绍兴柯岩古镇
2020/01/09 职场文书
Docker与K8s关系介绍不会Docker也可以使用K8s
2022/06/25 Servers