详解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 相关文章推荐
如何让easyui gridview 宽度自适应窗口改变及fitColumns应用
Jan 25 Javascript
Jquery 获取对象的几种方式介绍
Jan 17 Javascript
jquery带有索引按钮且自动轮播切换特效代码分享
Sep 15 Javascript
跟我学习javascript的call(),apply(),bind()与回调
Nov 16 Javascript
D3.js封装文本实现自动换行和旋转平移等功能
Oct 14 Javascript
Node.js设置CORS跨域请求中多域名白名单的方法
Mar 28 Javascript
JS实现下拉菜单列表与登录注册弹窗效果
Aug 10 Javascript
js实现简易计算器功能
Oct 18 Javascript
JS插件amCharts实现绘制柱形图默认显示数值功能示例
Nov 26 Javascript
vue使用map代替Aarry数组循环遍历的方法
Apr 30 Javascript
jQuery 选择方法及$(this)用法实例分析
May 19 jQuery
24个ES6方法解决JS实际开发问题(小结)
May 31 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
桌面中心(三)修改数据库
2006/10/09 PHP
php的GD库imagettftext函数解决中文乱码问题
2015/01/24 PHP
详解PHP的Yii框架中日志的相关配置及使用
2015/12/08 PHP
有关PHP 中 config.m4 的探索
2020/08/26 PHP
自己开发Dojo的建议框架
2008/09/24 Javascript
js 页面传参数时 参数值含特殊字符的问题
2009/12/13 Javascript
js 禁用只读文本框获得焦点时的退格键
2010/04/25 Javascript
jQuery .attr()和.removeAttr()方法操作元素属性示例
2013/07/16 Javascript
自动设置iframe大小的jQuery代码
2013/09/11 Javascript
javascript实现的平方米、亩、公顷单位换算小程序
2014/08/11 Javascript
javascript对中文按照拼音排序代码
2014/08/20 Javascript
一个css与js结合的下拉菜单支持主流浏览器
2014/10/08 Javascript
JavaScript判断是否为数组的3种方法及效率比较
2015/04/01 Javascript
jQuery数据类型小结(14个)
2016/01/08 Javascript
JavaScript动态生成二维码图片
2016/04/20 Javascript
原生js开发的日历插件
2017/02/04 Javascript
vue.js 获取当前自定义属性值
2017/06/01 Javascript
解决ztree搜索中多级菜单展示不全问题
2017/07/05 Javascript
webpack vue项目开发环境局域网访问方法
2018/03/20 Javascript
VUE使用 wx-open-launch-app 组件开发微信打开APP功能
2020/08/11 Javascript
python创建关联数组(字典)的方法
2015/05/04 Python
Django中url的反向查询的方法
2018/03/14 Python
详谈pandas中agg函数和apply函数的区别
2018/04/20 Python
Python中关于浮点数的冷知识
2019/09/22 Python
Python散点图与折线图绘制过程解析
2019/11/30 Python
如何导出python安装的所有模块名称和版本号到文件中
2020/06/05 Python
python 实现非极大值抑制算法(Non-maximum suppression, NMS)
2020/10/15 Python
CSS3 三维变形实现立体方块特效源码
2016/12/15 HTML / CSS
可以使用抽象函数重写基类中的虚函数吗
2013/06/02 面试题
电子信息毕业生自荐信
2013/11/16 职场文书
物业工作计划书
2014/01/10 职场文书
cf收人广告词
2014/03/14 职场文书
低碳环保口号
2014/06/12 职场文书
效能风暴心得体会
2014/09/04 职场文书
2015年机关党建工作总结
2015/05/22 职场文书
Spring中的使用@Async异步调用方法
2021/11/01 Java/Android