详解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 相关文章推荐
javascript事件模型代码
Jul 01 Javascript
js中使用DOM复制(克隆)指定节点名数据到新的XML文件中的代码
Jul 27 Javascript
JQuery实现点击div以外的位置隐藏该div窗口
Sep 13 Javascript
jquery实现的鼠标下拉滚动置顶效果
Jul 24 Javascript
JS验证IP,子网掩码,网关和MAC的方法
Jul 02 Javascript
浏览器检测JS代码(兼容目前各大主流浏览器)
Feb 21 Javascript
javascript基础语法——全面理解变量和标识符
Jun 02 Javascript
jQuery复制节点用法示例(clone方法)
Sep 08 Javascript
jquery+css3问卷答题卡翻页动画效果示例
Oct 26 Javascript
基于vue.js快速搭建图书管理平台
Oct 29 Javascript
webpack-url-loader 解决项目中图片打包路径问题
Feb 15 Javascript
js单线程的本质 Event Loop解析
Oct 29 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
一个PHP针对数字的加密解密类
2014/03/20 PHP
php使用Jpgraph创建柱状图展示年度收支表效果示例
2017/02/15 PHP
php实现支持中文的文件下载功能示例
2017/08/30 PHP
jQuery学习笔记之DOM对象和jQuery对象
2010/12/22 Javascript
js自定义事件及事件交互原理概述(一)
2013/02/01 Javascript
一款jquery特效编写的大度宽屏焦点图切换特效的实例代码
2013/08/05 Javascript
修复bash漏洞的shell脚本分享
2014/12/31 Javascript
Javascript中数组方法汇总(推荐)
2015/04/01 Javascript
基于原生JS实现图片裁剪
2016/08/01 Javascript
three.js绘制地球、飞机与轨迹的效果示例
2017/02/28 Javascript
JS字符串长度判断,超出进行自动截取的实例(支持中文)
2017/03/06 Javascript
简单谈谈require模块化jquery和angular的问题
2017/06/23 jQuery
微信小程序 动画的简单实例
2017/10/12 Javascript
基于 Vue 实现一个酷炫的 menu插件
2017/11/14 Javascript
javaScript 连接打印机,打印小票的实例
2017/12/29 Javascript
微信小程序与后台PHP交互的方法实例分析
2018/12/10 Javascript
Element中的Cascader(级联列表)动态加载省\市\区数据的方法
2019/03/27 Javascript
使用layui的router来进行传参的实现方法
2019/09/06 Javascript
vue 指令和过滤器的基本使用(品牌管理案例)
2019/11/04 Javascript
js布局实现单选按钮控件
2020/01/17 Javascript
[53:38]OG vs LGD 2018国际邀请赛淘汰赛BO3 第三场 8.26
2018/08/30 DOTA
python实现删除文件与目录的方法
2014/11/10 Python
python实现的简单文本类游戏实例
2015/04/28 Python
python 简单的绘图工具turtle使用详解
2017/06/21 Python
python使用suds调用webservice接口的方法
2019/01/03 Python
python日志模块logbook使用方法
2019/09/19 Python
python通过移动端访问查看电脑界面
2020/01/06 Python
使用分层画布来优化HTML5渲染的教程
2015/05/08 HTML / CSS
strlen的几种不同实现方法
2013/05/31 面试题
大学生蛋糕店创业计划书
2014/01/13 职场文书
小学生家长评语集锦
2014/01/30 职场文书
大学新生入学教育方案
2014/05/16 职场文书
公务员政审材料范文
2014/12/23 职场文书
2016年社区“6.26”禁毒日宣传活动总结
2016/04/05 职场文书
pandas:get_dummies()与pd.factorize()的用法及区别说明
2021/05/21 Python
实现GO语言对数组切片去重
2022/04/20 Golang