详解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 相关文章推荐
Jsonp 跨域的原理以及Jquery的解决方案
May 18 Javascript
基于jsTree的无限级树JSON数据的转换代码
Jul 27 Javascript
jquery实现搜索框常见效果的方法
Jan 22 Javascript
AngularJS内置指令
Feb 04 Javascript
浅析JavaScript 调试方法和技巧
Oct 22 Javascript
JavaScript制作淘宝星级评分效果的思路
Jun 23 Javascript
js canvas实现擦除动画
Jul 16 Javascript
JS完成画圆圈的小球
Mar 07 Javascript
bootstrap tooltips在 angularJS中的使用方法
Apr 10 Javascript
JavaScript实现拖动对话框效果的实现代码
Oct 12 Javascript
前端JS获取URL参数的4种方法总结
Apr 05 Javascript
vue-treeselect的基本用法以及解决点击无法出现拉下菜单
Apr 30 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
咖啡豆的最常见发酵处理方法,详细了解一下
2021/03/03 冲泡冲煮
多重?l件?合查?(二)
2006/10/09 PHP
PHP将HTML转换成文本的实现代码
2015/01/21 PHP
ThinkPHP中html:list标签用法分析
2016/01/09 PHP
Symfony2使用第三方库Upload制作图片上传实例详解
2016/02/04 PHP
PHP创建文件及写入数据(覆盖写入,追加写入)的方法详解
2019/02/15 PHP
用php定义一个数组最简单的方法
2019/10/04 PHP
javascript 三种编解码方式
2010/02/01 Javascript
js 纯数字不重复排列的另类方法
2010/07/17 Javascript
JavaScript取得鼠标绝对位置程序代码介绍
2012/09/16 Javascript
JavaScript高级程序设计(第3版)学习笔记10 再访js对象
2012/10/11 Javascript
js显示时间 js显示最后修改时间
2013/01/02 Javascript
jQuery插件jQuery-JSONP开发ajax调用使用注意事项
2013/11/22 Javascript
jquery实现网页查找功能示例分享
2014/02/12 Javascript
javascript实现控制文字大中小显示
2015/04/28 Javascript
jQuery实现日期联动效果实例
2016/07/26 Javascript
Nodejs高扩展性的模板引擎 functmpl简介
2017/02/13 NodeJs
详解ionic本地相册、拍照、裁剪、上传(单图完全版)
2017/10/10 Javascript
使用webpack搭建vue环境的教程详解
2019/12/31 Javascript
微信小程序实现上传多个文件 超过10个
2020/03/30 Javascript
Vue-cli打包后如何本地查看的操作
2020/09/02 Javascript
JS removeAttribute()方法实现删除元素的某个属性
2021/01/11 Javascript
python读文件逐行处理的示例代码分享
2013/12/27 Python
python difflib模块示例讲解
2017/09/13 Python
python实现超级玛丽游戏
2020/03/18 Python
Python tkinter制作单机五子棋游戏
2020/09/14 Python
Bootstrap 学习分享
2012/11/12 HTML / CSS
伊芙丽官方旗舰店:中国淑女一线品牌
2017/12/01 全球购物
中专毕业生自我鉴定范文
2013/11/09 职场文书
党员国庆节演讲稿范文2014
2014/09/21 职场文书
学困生转化工作总结
2015/08/13 职场文书
Python中使用Lambda函数的5种用法
2021/04/01 Python
python 用递归实现通用爬虫解析器
2021/04/16 Python
浅谈mysql增加索引不生效的几种情况
2021/06/23 MySQL
vue使用wavesurfer.js解决音频可视化播放问题
2022/04/04 Vue.js
vue组件冲突之引用另一个组件出现组件不显示的问题
2022/04/13 Vue.js