详解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/jQuery 表单美化插件小结
Feb 14 Javascript
深入理解JavaScript 闭包究竟是什么
Apr 12 Javascript
js加载读取内容及显示与隐藏div示例
Feb 13 Javascript
javascript巧用eval函数组装表单输入项为json对象的方法
Nov 25 Javascript
使用vue.js实现checkbox的全选和多个的删除功能
Feb 17 Javascript
javaScript之split与join的区别(详解)
Nov 08 Javascript
微信小程序实现给嵌套template模板传递数据的方式总结
Dec 18 Javascript
vue实现搜索过滤效果
May 28 Javascript
详解微信小程序支付流程与梳理
Jul 16 Javascript
在Node.js中将SVG图像转换为PNG,JPEG,TIFF,WEBP和HEIF格式的方法
Aug 22 Javascript
vue获取data数据改变前后的值方法
Nov 07 Javascript
JavaScript实现留言板案例
Mar 17 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 JSON出错:Cannot use object of type stdClass as array解决方法
2014/08/16 PHP
详解php与ethereum客户端交互
2018/04/28 PHP
javascript 客户端验证上传图片的大小(兼容IE和火狐)
2009/08/15 Javascript
Prototype的Class.create函数解析
2011/09/22 Javascript
JQuery插件Style定制化方法的分析与比较
2012/05/03 Javascript
javascript操作JSON的要领总结
2012/12/09 Javascript
js关闭父窗口时关闭子窗口
2013/04/01 Javascript
jCallout 轻松实现气泡提示功能
2013/09/22 Javascript
jQuery过滤选择器详解
2015/01/13 Javascript
javascript实现点击按钮弹出一个可关闭层窗口同时网页背景变灰的方法
2015/05/13 Javascript
你有必要知道的25个JavaScript面试题
2015/12/29 Javascript
javascript动态获取登录时间和在线时长
2016/02/25 Javascript
D3.js实现饼状图的方法详解
2016/09/21 Javascript
vue+element+Java实现批量删除功能
2019/04/08 Javascript
webpack4 optimization使用总结
2019/11/10 Javascript
解决vue语法会有延迟加载显现{{xxx}}的问题
2019/11/14 Javascript
[01:45]2014DOTA2 TI预选赛预选赛 战前探营!
2014/05/21 DOTA
[01:43]深扒TI7聊天轮盘语音出处4
2017/05/11 DOTA
[08:56]DOTA2-DPC中国联赛2月23日Recap集锦
2021/03/11 DOTA
Python中的模块和包概念介绍
2015/04/13 Python
Python 类与元类的深度挖掘 I【经验】
2016/05/06 Python
Python SQLite3数据库日期与时间常见函数用法分析
2017/08/14 Python
git进行版本控制心得详谈
2017/12/10 Python
Django实现支付宝付款和微信支付的示例代码
2018/07/25 Python
Python生成器generator用法示例
2018/08/10 Python
widows下安装pycurl并利用pycurl请求https地址的方法
2018/10/15 Python
python之生产者消费者模型实现详解
2019/07/27 Python
Python如何使用内置库matplotlib绘制折线图
2020/02/24 Python
Django values()和value_list()的使用
2020/03/31 Python
pyspark 随机森林的实现
2020/04/24 Python
凯特·丝蓓英国官网:Kate Spade英国
2016/11/07 全球购物
求职推荐信
2013/10/28 职场文书
2014迎新年晚会策划方案
2014/02/23 职场文书
学前班语言教学计划
2015/01/20 职场文书
2019求职信大礼包
2019/05/15 职场文书
导游词之崇武古城
2019/10/07 职场文书