详解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 相关文章推荐
ext jquery 简单比较
Apr 07 Javascript
JS使用replace()方法和正则表达式进行字符串的搜索与替换实例
Apr 10 Javascript
js确认框confirm()用法实例详解
Jan 07 Javascript
最实用的jQuery分页插件
Oct 09 Javascript
Angular异步变同步处理方法
Aug 13 Javascript
详解在vue-cli中使用graphql即vue-apollo的用法
Sep 08 Javascript
vue+axios 前端实现登录拦截的两种方式(路由拦截、http拦截)
Oct 24 Javascript
微信小程序云开发之使用云存储
May 17 Javascript
pageGroup.js实现分页功能
Jul 27 Javascript
vue中进行微博分享的实例讲解
Oct 14 Javascript
详解node.js 事件循环
Jul 22 Javascript
javascript解析json格式的数据方法详解
Aug 07 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
Yii2 批量插入、更新数据实例
2017/03/15 PHP
IIS 7.5 asp Session超时时间设置方法
2017/04/17 PHP
Smarty模板语法详解
2019/07/20 PHP
CentOS7系统搭建LAMP及更新PHP版本操作详解
2020/03/26 PHP
JavaScript设计模式之单例模式实例
2014/09/24 Javascript
使表格的标题列可左右拉伸jquery插件封装
2014/11/24 Javascript
jQuery中document与window以及load与ready 区别详解
2014/12/29 Javascript
jQuery实现3D文字特效的方法
2015/03/10 Javascript
javascript判断变量是否有值的方法
2015/04/20 Javascript
jquery仿京东侧边栏导航效果
2017/03/02 Javascript
AngularJS读取JSON及XML文件的方法示例
2017/05/25 Javascript
Nodejs中怎么实现函数的串行执行
2019/03/02 NodeJs
微信小程序非跳转式组件授权登录的方法示例
2019/05/22 Javascript
详细介绍解决vue和jsp结合的方法
2020/02/06 Javascript
纯JS开发baguetteBox.js响应式画廊插件
2020/06/28 Javascript
微信小程序中target和currentTarget的区别小结
2020/11/06 Javascript
小程序实现tab标签页
2020/11/16 Javascript
python搜索指定目录的方法
2015/04/29 Python
用Python实现KNN分类算法
2017/12/22 Python
python如何定义带参数的装饰器
2018/03/20 Python
python如何为被装饰的函数保留元数据
2018/03/21 Python
Linux下安装python3.6和第三方库的教程详解
2018/11/09 Python
如何使用python把ppt转换成pdf
2019/06/29 Python
python try except返回异常的信息字符串代码实例
2019/08/15 Python
一款基于css3的动画按钮代码教程
2014/11/23 HTML / CSS
Html5之title吸顶功能
2018/06/04 HTML / CSS
html5移动端自适应布局的实现
2020/04/15 HTML / CSS
Vrbo西班牙:预订您的度假公寓(公寓、乡村房屋…)
2020/04/27 全球购物
12.4全国法制宣传日活动总结
2014/11/01 职场文书
幼儿园教师自荐书
2015/03/06 职场文书
汽车4S店前台接待岗位职责
2015/04/03 职场文书
2019新员工试用期转正工作总结范文
2019/08/21 职场文书
Java实现多文件上传功能
2021/06/30 Java/Android
MySQL表锁、行锁、排它锁及共享锁的使用详解
2022/04/02 MySQL
Golang 对es的操作实例
2022/04/20 Golang
安装harbor作为docker镜像仓库的问题
2022/06/14 Servers