详解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 相关文章推荐
How to Auto Include a Javascript File
Feb 02 Javascript
JavaScript中实现单体模式分享
Jan 29 Javascript
JavaScript Sort 的一个错误用法示例
Mar 20 Javascript
input file上传 图片预览功能实例代码
Oct 25 Javascript
node操作mysql数据库实例详解
Mar 17 Javascript
详解JavaScript调用栈、尾递归和手动优化
Jun 03 Javascript
深入理解Vuex 模块化(module)
Sep 26 Javascript
vue router-link传参以及参数的使用实例
Nov 10 Javascript
security.js实现的RSA加密功能示例
Jun 06 Javascript
JavaScript生成一个不重复的ID的方法示例
Sep 16 Javascript
vue 自定义右键样式的实例代码
Nov 06 Javascript
学习 Vue.js 遇到的那些坑
Feb 02 Vue.js
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
超人钢铁侠联手合作?美漫作家呼吁DC漫威合作联动以抵抗疫情
2020/04/09 欧美动漫
php修改NetBeans默认字体的大小
2013/07/02 PHP
php上传图片存入数据库示例分享
2014/03/11 PHP
PHP静态成员变量和非静态成员变量详解
2017/02/14 PHP
php使用lua+redis实现限流,计数器模式,令牌桶模式
2019/04/04 PHP
PHP写API输出的时用echo的原因详解
2019/04/28 PHP
javascript DOM编程实例(智播客学习)
2009/11/23 Javascript
Javascript 面向对象编程(coolshell)
2012/03/18 Javascript
js控制input框只读实现示例
2014/01/20 Javascript
js+div实现图片滚动效果代码
2014/02/10 Javascript
JavaScript获取数组最小值和最大值的方法
2015/06/09 Javascript
jquery马赛克拼接翻转效果代码分享
2015/08/24 Javascript
微信小程序选择图片和放大预览图片功能
2017/11/02 Javascript
vscode中vue-cli项目es-lint的配置方法
2018/07/30 Javascript
three.js利用gpu选取物体并计算交点位置的方法示例
2019/11/25 Javascript
jQuery实现的移动端图片缩放功能组件示例
2020/05/01 jQuery
uni-app微信小程序登录授权的实现
2020/05/22 Javascript
用python删除java文件头上版权信息的方法
2014/07/31 Python
python读取tif图片时保留其16bit的编码格式实例
2020/01/13 Python
利用keras加载训练好的.H5文件,并实现预测图片
2020/01/24 Python
django2.2 和 PyMySQL版本兼容问题
2020/02/17 Python
查看keras各种网络结构各层的名字方式
2020/06/11 Python
Python应用实现双指数函数及拟合代码实例
2020/06/19 Python
python中sys模块是做什么用的
2020/08/16 Python
HTML5制作酷炫音频播放器插件图文教程
2014/12/30 HTML / CSS
美国著名珠宝品牌之一:Jared The Galleria Of Jewelry
2016/10/01 全球购物
国家地理在线商店:Shop National Geographic
2018/06/30 全球购物
医校毕业生自我鉴定
2014/01/25 职场文书
工地质量标语
2014/06/12 职场文书
争先创优公开承诺书
2014/08/30 职场文书
先进工作者事迹材料
2014/12/23 职场文书
杭州西湖英语导游词
2015/02/03 职场文书
学习新党章心得体会2016
2016/01/15 职场文书
《珍珠鸟》教学反思
2016/02/16 职场文书
三好学生评选事迹材料(2016精选版)
2016/02/25 职场文书
Pygame Draw绘图函数的具体使用
2021/11/17 Python