详解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 相关文章推荐
Sample script that deletes a SQL Server database
Jun 16 Javascript
javascript demo 基本技巧
Dec 18 Javascript
javascript 冒泡排序 正序和倒序实现代码
Dec 14 Javascript
JS返回上一页实例代码通过图片和按钮分别实现
Aug 16 Javascript
很全面的JavaScript常用功能汇总集合
Jan 22 Javascript
原生js实现回复评论功能
Jan 18 Javascript
jQuery动态追加页面数据以及事件委托详解
May 06 jQuery
Angular2之二级路由详解
Aug 31 Javascript
详解小程序不同页面之间通讯的解决方案
Nov 23 Javascript
Vue性能优化的方法
Jul 30 Javascript
关于angular 8.1使用过程中的一些记录
Nov 25 Javascript
vue中activated的用法
Jan 03 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
深入理解curl类,可用于模拟get,post和curl下载
2013/06/08 PHP
php使用cookie保存用户登录的用户名实例
2015/01/26 PHP
php加密之discuz内容经典加密方式实例详解
2017/02/04 PHP
PHP实现的观察者模式实例
2017/06/21 PHP
IE6浏览器下resize事件被执行了多次解决方法
2012/12/11 Javascript
nodejs中exports与module.exports的区别详细介绍
2013/01/14 NodeJs
如何让easyui gridview 宽度自适应窗口改变及fitColumns应用
2013/01/25 Javascript
[JSF]使用DataModel处理表行事件的实例代码
2013/08/05 Javascript
javascript教程之不完整的继承(js原型链)
2014/01/13 Javascript
JavaScript中双符号的运算详解
2017/03/12 Javascript
推荐三款日期选择插件(My97DatePicker、jquery.datepicker、Mobiscroll)
2017/04/21 jQuery
JavaScript实现省市县三级级联特效
2017/05/16 Javascript
浅析node Async异步处理模块用例分析及常用方法介绍
2017/11/17 Javascript
JavaScript创建对象的常用方式总结
2018/08/10 Javascript
详解基于Vue,Nginx的前后端不分离部署教程
2018/12/04 Javascript
vscode配置vue下的es6规范自动格式化详解
2019/03/20 Javascript
JS面向对象编程实现的Tab选项卡案例详解
2020/03/03 Javascript
微信小程序实现选项卡滑动切换
2020/10/22 Javascript
关于vue 项目中浏览器跨域的配置问题
2020/11/10 Javascript
vue表单验证之禁止input输入框输入空格
2020/12/03 Vue.js
python文件和目录操作方法大全(含实例)
2014/03/12 Python
用Python编写一个简单的俄罗斯方块游戏的教程
2015/04/03 Python
python解析基于xml格式的日志文件
2017/02/25 Python
django使用JWT保存用户登录信息
2020/04/22 Python
python thrift 实现 单端口多服务的过程
2020/06/08 Python
类、抽象类、接口的差异
2016/06/13 面试题
可以使用抽象函数重写基类中的虚函数吗
2013/06/02 面试题
护理毕业生自我鉴定
2014/02/11 职场文书
人事专员的职责
2014/02/26 职场文书
科研课题实施方案
2014/03/18 职场文书
和睦家庭事迹
2014/05/14 职场文书
七夕情人节促销方案
2014/06/07 职场文书
企业宣传语大全
2015/07/13 职场文书
企业转让协议书(范文2篇)
2019/08/15 职场文书
mysql优化之query_cache_limit参数说明
2021/07/01 MySQL
Python实现抖音热搜定时爬取功能
2022/03/16 Python