详解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 相关文章推荐
将HTMLCollection/NodeList/伪数组转换成数组的实现方法
Jun 20 Javascript
jQuery学习笔记 操作jQuery对象 文档处理
Sep 19 Javascript
jquery mobile实现拨打电话功能的几种方法
Aug 05 Javascript
JS Replace 全部替换字符的用法小结
Dec 24 Javascript
详谈JavaScript 匿名函数及闭包
Nov 14 Javascript
编写简单的jQuery提示插件
Dec 21 Javascript
jquery仿百度经验滑动切换浏览效果
Apr 14 Javascript
基于Bootstrap里面的Button dropdown打造自定义select
May 30 Javascript
bootstrap输入框组代码分享
Jun 07 Javascript
Vue中添加手机验证码组件功能操作方法
Dec 07 Javascript
vue实现提示保存后退出的方法
Mar 15 Javascript
vue组件是如何解析及渲染的?
Jan 13 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
解决form中action属性后面?传递参数 获取不到的问题
2017/07/21 PHP
php批量转换文件夹下所有文件编码的函数类
2017/08/06 PHP
PHP中abstract(抽象)、final(最终)和static(静态)原理与用法详解
2020/06/05 PHP
原生Js与jquery的多组处理, 仅展开一个区块的折叠效果
2011/01/09 Javascript
javascript中的遍历for in 以及with的用法
2014/12/22 Javascript
微信小程序 Image API实例详解
2016/09/30 Javascript
JavaScript 事件流、事件处理程序及事件对象总结
2017/04/01 Javascript
深入理解JavaScript继承的多种方式和优缺点
2017/05/12 Javascript
vue2.0项目实现路由跳转的方法详解
2018/06/21 Javascript
angularJs复选框checkbox选中进行ng-show显示隐藏的方法
2018/10/08 Javascript
微信小程序实现自动定位功能
2018/10/31 Javascript
JS学习笔记之原型链和利用原型实现继承详解
2019/05/29 Javascript
js 下拉菜单点击旁边收起实现(踩坑记)
2019/09/29 Javascript
vue 实现移动端键盘搜索事件监听
2019/11/06 Javascript
怎么理解wx.navigateTo的events参数使用详情
2020/05/18 Javascript
[04:02]2014DOTA2国际邀请赛 BBC每日综述中国战队将再度登顶
2014/07/21 DOTA
pytyon 带有重复的全排列
2013/08/13 Python
详细解析Python中的变量的数据类型
2015/05/13 Python
Python解析最简单的验证码
2016/01/07 Python
python 实现批量xls文件转csv文件的方法
2018/10/23 Python
python利用Tesseract识别验证码的方法示例
2019/01/21 Python
你还在@微信官方?聊聊Python生成你想要的微信头像
2019/09/25 Python
Python程序控制语句用法实例分析
2020/01/14 Python
python代码区分大小写吗
2020/06/17 Python
用python对excel进行操作(读,写,修改)
2020/12/25 Python
基于PyTorch中view的用法说明
2021/03/03 Python
世界上最全面的汽车零部件和配件集合:JC Whitney
2016/09/04 全球购物
挪威户外活动服装和装备购物网站:Bergfreunde挪威
2016/10/20 全球购物
Booking.com英国官网:全球酒店在线预订网站
2018/04/21 全球购物
navabi英国:设计师大码女装
2019/06/25 全球购物
创意广告词
2014/03/17 职场文书
2014年创先争优活动总结
2014/05/04 职场文书
驳回起诉裁定书
2015/05/19 职场文书
小学六年级毕业感言
2015/07/30 职场文书
Matplotlib绘制混淆矩阵的实现
2021/05/27 Python
vue数据字典取键值项目的字典问题
2022/04/12 Vue.js