详解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入门教程(2) JS基础知识
Jan 31 Javascript
使用jQuery向asp.net Mvc传递复杂json数据-ModelBinder篇
May 07 Javascript
JavaScript代码判断点击第几个按钮
Dec 13 Javascript
jquery获取点击控件的绝对位置简单实例
Oct 13 Javascript
微信小程序 删除项目工程实现步骤
Nov 10 Javascript
JavaScript使用delete删除数组元素用法示例【数组长度不变】
Jan 17 Javascript
详解JS中的柯里化(currying)
Aug 17 Javascript
详解基于Vue+Koa的pm2配置
Oct 24 Javascript
微信小程序实现搜索功能并跳转搜索结果页面
May 18 Javascript
微信小程序静默登录的实现代码
Jan 08 Javascript
在Vuex中Mutations修改状态操作
Jul 24 Javascript
vue3.0 加载json的方法(非ajax)
Oct 26 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
phpmyadmin 常用选项设置详解版
2010/03/07 PHP
php-cli简介(不会Shell语言一样用Shell)
2013/06/03 PHP
php array_merge函数使用需要注意的一个问题
2015/03/30 PHP
php 多进程编程父进程的阻塞与非阻塞实例分析
2020/02/22 PHP
解析javascript 实用函数的使用详解
2013/05/10 Javascript
javascript截取字符串(通过substring实现并支持中英文混合)
2013/06/24 Javascript
java与javascript之间json格式数据互转介绍
2013/10/29 Javascript
浅谈JavaScript 框架分类
2014/11/10 Javascript
实例解析jQuery插件EasyUI最常用的表单验证规则
2015/11/29 Javascript
jquery 重写 ajax提交并判断权限后 使用load方法报错解决方法
2016/01/19 Javascript
JS实现图文并茂的tab选项卡效果示例【附demo源码下载】
2016/09/21 Javascript
Javascript实现登录记住用户名和密码功能
2017/03/22 Javascript
layer实现关闭弹出层刷新父界面功能详解
2017/11/15 Javascript
原生js实现form表单序列化的方法
2018/08/02 Javascript
使用 Node.js 实现图片的动态裁切及算法实例代码详解
2018/09/29 Javascript
在vue中使用jsonp进行跨域请求接口操作
2020/10/29 Javascript
JavaScript实现图片放大预览效果
2020/11/02 Javascript
python处理文本文件并生成指定格式的文件
2014/07/31 Python
Python的Bottle框架中实现最基本的get和post的方法的教程
2015/04/30 Python
python实现学生信息管理系统
2020/04/05 Python
sublime python3 输入换行不结束的方法
2018/04/19 Python
python 划分数据集为训练集和测试集的方法
2018/12/11 Python
python简单贪吃蛇开发
2019/01/28 Python
详解python:time模块用法
2019/03/25 Python
用django设置session过期时间的方法解析
2019/08/05 Python
python将字典列表导出为Excel文件的方法
2019/09/02 Python
np.random.seed() 的使用详解
2020/01/14 Python
Python新手如何进行闭包时绑定变量操作
2020/05/29 Python
基于Html5实现的react拖拽排序组件示例
2018/08/13 HTML / CSS
工作自我评价怎么写
2014/01/29 职场文书
2014年中班元旦活动方案
2014/02/14 职场文书
2014公安机关纪律作风整顿思想汇报
2014/09/13 职场文书
四风自我剖析材料思想汇报
2014/10/01 职场文书
解除同居协议书
2015/01/29 职场文书
化验室岗位职责
2015/02/14 职场文书
微信小程序用户授权最佳实践指南
2021/05/08 Javascript