详解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函数ajax
Aug 20 Javascript
JavaScript高级程序设计阅读笔记(五) ECMAScript中的运算符(一)
Feb 27 Javascript
原生js编写设为首页兼容ie、火狐和谷歌
Jun 05 Javascript
JavaScript实现的石头剪刀布游戏源码分享
Aug 22 Javascript
javascript中HTMLDOM操作详解
Dec 11 Javascript
网页中JS函数自动执行常用三种方法
Mar 30 Javascript
Angular.js中window.onload(),$(document).ready()的写法浅析
Sep 28 Javascript
Vue Element使用icon图标教程详解(第三方)
Feb 07 Javascript
详解如何使用webpack打包JS
Jun 21 Javascript
vue使用swiper.js重叠轮播组建样式
Nov 14 Javascript
基于JQuery实现页面定时弹出广告
May 08 jQuery
el-table-column 内容不自动换行的解决方法
Aug 14 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
PHP 高手之路(三)
2006/10/09 PHP
php批量删除数据
2007/01/18 PHP
php抽象方法和抽象类实例分析
2016/12/07 PHP
jquery 日期分离成年月日的代码
2010/05/14 Javascript
JavaScript高级程序设计 DOM学习笔记
2011/09/10 Javascript
JavaScript高级程序设计 阅读笔记(四) ECMAScript中的类型转换
2012/02/27 Javascript
解析Jquery取得iframe中元素的几种方法
2013/07/04 Javascript
js 实现菜单左右滚动显示示例介绍
2013/11/21 Javascript
利用JQuery制作符合Web标准的QQ弹出消息
2014/01/14 Javascript
使用JavaScript+canvas实现图片裁剪
2015/01/30 Javascript
NodeJS使用jQuery选择器操作DOM
2015/02/13 NodeJs
JS实现slide文字框缩放伸展效果代码
2015/11/05 Javascript
深入浅析JavaScript中prototype和proto的关系
2015/11/15 Javascript
AngularJS 中使用Swiper制作滚动图不能滑动的解决方法
2016/11/15 Javascript
拖动时防止选中
2017/02/03 Javascript
如何使用bootstrap框架 bootstrap入门必看!
2017/04/13 Javascript
Javascript ES6中对象类型Sets的介绍与使用详解
2017/07/17 Javascript
JavaScript学习笔记之函数记忆
2017/09/06 Javascript
ES6 新增的创建数组的方法(小结)
2019/08/01 Javascript
微信公众号平台接口开发 获取微信服务器IP地址方法解析
2019/08/14 Javascript
vue addRoutes路由动态加载操作
2020/08/04 Javascript
vue将文件/图片批量打包下载zip的教程
2020/10/21 Javascript
Python中的字典与成员运算符初步探究
2015/10/13 Python
Python argv用法详解
2016/01/08 Python
Python3批量移动指定文件到指定文件夹方法示例
2019/09/02 Python
浅谈matplotlib.pyplot与axes的关系
2020/03/06 Python
使用Python爬取弹出窗口信息的实例
2020/03/14 Python
Python扫描端口的实现
2021/01/25 Python
毕业生自我鉴定范文
2013/11/08 职场文书
历史专业毕业生的自我鉴定
2013/11/15 职场文书
建筑专业毕业生推荐信
2013/11/21 职场文书
教师竞聘演讲稿
2014/05/16 职场文书
领导班子党的群众路线对照检查材料
2014/09/25 职场文书
2014年项目工作总结
2014/11/24 职场文书
Win11查看设备管理器
2022/04/19 数码科技
Android开发手册自定义Switch开关按钮控件
2022/06/10 Java/Android