详解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中的parseInt使用技巧
Sep 03 Javascript
js下用gb2312编码解码实现方法
Dec 31 Javascript
一个基于jquery的图片切换效果
Jul 06 Javascript
为jQuery.Treeview添加右键菜单的实现代码
Oct 22 Javascript
Javascript基础教程之数据类型 (布尔型 Boolean)
Jan 18 Javascript
kindeditor修复会替换script内容的问题
Apr 03 Javascript
JQuery中ajax方法访问web服务实例
Jul 18 Javascript
xmlplus组件设计系列之按钮(2)
Apr 26 Javascript
详解微信小程序设置底部导航栏目方法
Jun 29 Javascript
解决使用vue.js路由后失效的问题
Mar 17 Javascript
vue自定义switch开关组件,实现样式可自行更改
Nov 01 Javascript
微信小程序动态设置图片大小的方法
Nov 21 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 cache类代码(php数据缓存类)
2010/04/15 PHP
PHP 利用AJAX获取网页并输出的实现代码(Zjmainstay)
2012/08/31 PHP
PHP中使用socket方式GET、POST数据实例
2015/04/02 PHP
PHP加密3DES报错 Call to undefined function: mcrypt_module_open() 如何解决
2016/04/17 PHP
浅谈使用 Yii2 AssetBundle 中 $publishOptions 的正确姿势
2017/11/08 PHP
Laravel框架实现多数据库连接操作详解
2019/07/12 PHP
区分JS中的undefined,null,"",0和false
2007/03/08 Javascript
js中document.getElementByid、document.all和document.layers区分介绍
2011/12/08 Javascript
jquery获取tr并更改tr内容示例代码
2014/02/13 Javascript
jquery根据属性和index来查找属性值并操作
2014/07/25 Javascript
javascript手工制作悬浮菜单
2015/02/12 Javascript
跟我学习javascript的严格模式
2015/11/16 Javascript
基于Bootstrap实现的下拉菜单手机端不能选择菜单项的原因附解决办法
2016/07/22 Javascript
js实现统计字符串中特定字符出现个数的方法
2016/08/02 Javascript
js监听键盘事件的方法_原生和jquery的区别详解
2016/10/10 Javascript
浅析Jquery操作select
2016/12/13 Javascript
Vue2.0实现1.0的搜索过滤器功能实例代码
2017/03/20 Javascript
使用Node搭建reactSSR服务端渲染架构
2018/08/30 Javascript
浅谈React Event实现原理
2018/09/20 Javascript
小程序实现展开/收起的效果示例
2018/09/22 Javascript
利用jquery和BootStrap实现动态滚动条效果
2018/12/03 jQuery
JavaScript实现预览本地上传图片功能完整示例
2019/03/08 Javascript
JavaScript实现模态对话框实例
2020/01/13 Javascript
2020京东618叠蛋糕js脚本(亲测好用)
2020/06/02 Javascript
[00:28]DOTA2北京网鱼队选拔赛
2015/04/08 DOTA
Python人脸识别初探
2017/12/21 Python
使用Python爬取Json数据的示例代码
2020/12/07 Python
Foreo国际站:Foreo International
2018/10/29 全球购物
Vivo俄罗斯官方在线商店:中国智能手机品牌
2019/10/04 全球购物
Currentbody澳大利亚:美容仪专家
2019/11/11 全球购物
摄影助理岗位职责
2014/02/07 职场文书
信息管理专业自荐书
2014/06/05 职场文书
会计岗位职责
2015/02/03 职场文书
社团个人总结范文
2015/03/05 职场文书
高中生综合素质评价范文
2015/08/18 职场文书
2016年共产党员个人承诺书
2016/03/24 职场文书