详解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 相关文章推荐
js捕获鼠标右键菜单中的粘帖事件实现代码
Apr 01 Javascript
JavaScript中的this引用(推荐)
Aug 05 Javascript
jquery设置css样式的多种方法(总结)
Feb 21 Javascript
js获取指定时间的前几秒
Apr 05 Javascript
Angularjs 1.3 中的$parse实例代码
Sep 14 Javascript
ES6中的Promise代码详解
Oct 09 Javascript
vue watch自动检测数据变化实时渲染的方法
Jan 16 Javascript
webpack4+express+mongodb+vue实现增删改查的示例
Nov 08 Javascript
微信小程序学习笔记之登录API与获取用户信息操作图文详解
Mar 29 Javascript
D3.js(v3)+react 实现带坐标与比例尺的柱形图 (V3版本)
May 09 Javascript
详解微信小程序「渲染层网络层错误」的解决方法
Jan 06 Javascript
Html5生成验证码的示例代码
May 10 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
手把手教你使用DedeCms V3的在线采集图文教程
2007/04/03 PHP
PHP基于GD库的缩略图生成代码(支持jpg,gif,png格式)
2014/06/19 PHP
PHP自动生成表单代码分享
2015/06/19 PHP
Laravel学习教程之从入口到输出过程详解
2017/08/27 PHP
php判断文件上传图片格式的实例详解
2017/09/30 PHP
PHP 对象继承原理与简单用法示例
2020/04/21 PHP
jQuery EasyUI API 中文文档 - NumberBox数字框
2011/10/13 Javascript
js实现点击注册按钮开始读秒倒计时的小例子
2013/05/11 Javascript
jquery实现的可隐藏重现的靠边悬浮层实例代码
2013/05/27 Javascript
js返回上一页并刷新的多种实现方法
2014/02/26 Javascript
JS实现div居中示例
2014/04/17 Javascript
jQuery实现购物车计算价格功能的方法
2015/03/25 Javascript
javascript实现rgb颜色转换成16进制格式
2015/07/10 Javascript
jQuery绑定事件on()与弹窗的简要概述
2016/04/27 Javascript
bootstrap输入框组代码分享
2016/06/07 Javascript
JS实现漂亮的时间选择框效果
2016/08/20 Javascript
详解js的事件代理(委托)
2016/12/22 Javascript
详解vue事件对象、冒泡、阻止默认行为
2017/03/20 Javascript
JS实现手写parseInt的方法示例
2017/09/24 Javascript
Vue SSR 组件加载问题
2018/05/02 Javascript
JavaScript设计模式之构造函数模式实例教程
2018/07/02 Javascript
微信小程序实现卡片左右滑动效果的示例代码
2019/05/01 Javascript
JS实现简单的文字无缝上下滚动功能示例
2019/06/22 Javascript
vue实现滑动超出指定距离回顶部功能
2019/07/31 Javascript
JavaScript遍历数组的方法代码实例
2020/01/14 Javascript
Python使用matplotlib绘制三维图形示例
2018/08/25 Python
python爬取网易云音乐评论
2018/11/16 Python
基于python连接oracle导并出数据文件
2020/04/28 Python
Python基于callable函数检测对象是否可被调用
2020/10/16 Python
prAna官网:瑜伽、旅行和冒险服装
2019/03/10 全球购物
Chain Reaction Cycles俄罗斯:世界上最大的在线自行车商店
2019/08/27 全球购物
巡警年度自我鉴定
2014/02/21 职场文书
给女朋友的道歉短信
2015/05/12 职场文书
2015初中团委工作总结
2015/07/28 职场文书
Redis安装启动及常见数据类型
2021/04/14 Redis
Python 机器学习工具包SKlearn的安装与使用
2021/05/14 Python