详解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控制上传文件的大小
Oct 26 Javascript
使用jquery插件实现图片延迟加载技术详细说明
Mar 12 Javascript
用RadioButten或CheckBox实现div的显示与隐藏
Sep 21 Javascript
js加载读取内容及显示与隐藏div示例
Feb 13 Javascript
浅析javascript中的事件代理
Nov 06 Javascript
Vue制作Todo List网页
Apr 26 Javascript
微信小程序 新建登录页并实现tabBar隐藏
Jun 13 Javascript
vue-lazyload图片延迟加载插件的实例讲解
Feb 09 Javascript
vue 解决addRoutes动态添加路由后刷新失效问题
Jul 02 Javascript
JavaScript实现学生在线做题计时器功能
Dec 05 Javascript
Node.js在图片模板上生成二维码图片并附带底部文字说明实现详解
Aug 07 Javascript
js中的this的指向问题详解
Aug 29 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
提示Trying to clone an uncloneable object of class Imagic的解决
2011/10/27 PHP
JavaScript Distilled 基础知识与函数
2010/04/07 Javascript
js创建子窗口并且回传值示例代码
2013/07/02 Javascript
用RadioButten或CheckBox实现div的显示与隐藏
2013/09/21 Javascript
Js中使用hasOwnProperty方法检索ajax响应对象的例子
2014/12/08 Javascript
node.js中的fs.renameSync方法使用说明
2014/12/16 Javascript
微信小程序 自己制作小组件实例详解
2016/12/22 Javascript
浅谈React高阶组件
2018/03/28 Javascript
vue单页面应用打开新窗口显示跳转页面的实例
2018/09/21 Javascript
django使用channels2.x实现实时通讯
2018/11/28 Javascript
微信小程序云开发获取文件夹下所有文件(推荐)
2019/11/14 Javascript
Vue快速实现通用表单验证功能
2019/12/05 Javascript
nodejs中的异步编程知识点详解
2021/01/17 NodeJs
Windows系统配置python脚本开机启动的3种方法分享
2015/03/10 Python
使用Python下载歌词并嵌入歌曲文件中的实现代码
2015/11/13 Python
读取本地json文件,解析json(实例讲解)
2017/12/06 Python
如何安装多版本python python2和python3共存以及pip共存
2018/09/18 Python
Python实现的各种常见分布算法示例
2018/12/13 Python
Css3圆角边框制作代码
2015/11/18 HTML / CSS
丝芙兰法国官网:SEPHORA法国
2016/09/01 全球购物
德国狗狗用品在线商店:Schecker
2017/03/17 全球购物
MADE法国:提供原创设计师家具
2018/09/18 全球购物
META-INF文件夹中的MANIFEST.MF的作用
2016/06/21 面试题
管理学专业个人求职信范文
2013/12/13 职场文书
大学生文员专业个人求职信范文
2014/01/05 职场文书
幼儿园中班上学期评语
2014/04/18 职场文书
区域销售主管岗位职责
2014/06/15 职场文书
人大代表选举标语
2014/10/07 职场文书
党员组织生活会发言材料
2014/10/17 职场文书
干部作风建设工作总结
2014/10/29 职场文书
2014年图书室工作总结
2014/12/09 职场文书
六一领导慰问欢迎词
2015/01/26 职场文书
商务英语求职信范文
2015/03/19 职场文书
2019年度行政文员工作计划范本!
2019/07/04 职场文书
关于CSS浮动与取消浮动的问题
2021/06/28 HTML / CSS
星际争霸:毕姥爷vs解冻01
2022/04/01 星际争霸