javascript的事件触发器介绍的实现


Posted in Javascript onJune 05, 2014

事件触发器从字面意思上可以很好的理解,就是用来触发事件的,但是有些没有用过的朋友可能就会迷惑了,事件不是通常都由用户在页面上的实际操作来触发的吗?这个观点不完全正确,因为有些事件必须由程序来实现,如自定义事件,jQuery的ajax框架的一些自定义事件就必须由事件触发器来实现。当然,在一些特殊情况下,用事件触发器来触发事件比用户的实际操作来触发事件更方便。

对于实现事件触发器,浏览器都有原生的方法来支持,但是在兼容性上又有很大的出入,这种兼容性的问题完全在意料之中,IE有自己的方法,其他标准浏览器也有一套方法,不说谁的方法好与不好,对于WEB开发者来说搞出几套方法就是对开发人员的一种折磨。IE支持fireEvent方法来实现事件触发,标准浏览器支持dispatchEvent来实现事件触发,两面派的IE9是两者都支持。下面是出自prototype.js的源码(其实我是从司徒正美的博客复制过来的):

var fireEvent = function(element,event){
 if (document.createEventObject){
  // IE浏览器支持fireEvent方法
  var evt = document.createEventObject();
  return element.fireEvent('on'+event,evt)
 }
 else{
  // 其他标准浏览器使用dispatchEvent方法
  var evt = document.createEvent( 'HTMLEvents' );
  // initEvent接受3个参数:
  // 事件类型,是否冒泡,是否阻止浏览器的默认行为
  evt.initEvent(event, true, true);  
  return !element.dispatchEvent(evt);
 }
};

上面的方法可以兼容主流的浏览器以实现事件触发器的功能。但是对于一些封装好的事件处理系统,如jQuery的event模块,就没这么简单了,只能通过模拟来实现了。我在之前写过一个很简单的事件处理系统,最近又碰到自定义事件的需求,于是在之前的事件系统的基础上模拟了一个事件触发器,代码如下:

/**
 * 事件触发器
 * @param { Object } DOM元素
 * @param { String / Object } 事件类型 / event对象
 * @param { Array }  传递给事件处理函数的附加参数
 * @param { Boolean } 是否冒泡
 */
trigger : function( elem, event, data, isStopPropagation ){
 var type = event.type || event,
  // 冒泡的父元素,一直到document、window
  parent = elem.parentNode || 
   elem.ownerDocument || 
   elem === elem.ownerDocument && win,
  eventHandler = $.data( elem, type + 'Handler' ); isStopPropagation = typeof data === 'boolean' ? 
  data : (isStopPropagation || false);
 data = data && isArray( data ) ? data : [];
 // 创建自定义的event对象  
 event = typeof event === 'object' ? 
  event : {
   type : type,
   preventDefault : noop,
   stopPropagation : function(){
    isStopPropagation = true;
   }
  };
 event.target = elem;  
 data.unshift( event );
 if( eventHandler ){
  eventHandler.call( elem, data );
 }
 // 递归调用自身来模拟冒泡
 if( parent && !isStopPropagation ){
  data.shift();
  this.trigger( parent, event, data );
 }
}

模拟的原理并不难,给某元素绑定一个事件处理函数,如果有触发事件的实际操作就会执行相应的事件处理函数,所以要达到事件触发器的功能只要获取到相应的事件处理函数然后执行就差不多了,这是最基本的。

在实际的事件发生时浏览器会生成一个event对象,里面包含了一些事件发生时的属性和信息。如果没有实际的事件发生是没有这个event对象的,所以上面的代码也创建了一个event对象满足最基本的功能。

还有事件冒泡,如果没有实际的事件发生,自然也不会有冒泡的行为,那么如果要模拟冒泡的功能,就必须不断的查找父元素并检查是否绑定了相同类型的事件,直至到document和window为止,如果结构复杂,这种递归调用的方法性能估计会不怎么样。

最后是浏览器的默认行为,我觉得这个要去模拟相当麻烦,麻烦到不知如何去实现,比如a标签默认的跳转,我测试了jQuery的trigger,也没有实现,但是一些其他的行为貌似又在API手册中有介绍。毕竟这个功能不是很重要,暂时也没做过多的深究。

 

 

Javascript 相关文章推荐
IE与firefox之jquery用法区别
Oct 03 Javascript
Prototype 学习 工具函数学习($A方法)
Jul 12 Javascript
js去除重复字符串两种实现方法
Jan 09 Javascript
JS实现鼠标单击与双击事件共存
Mar 08 Javascript
Javascript 实现微信分享(QQ、朋友圈、分享给朋友)
Oct 21 Javascript
vue-cli如何添加less 以及sass
Jul 06 Javascript
详解ES6之用let声明变量以及let loop机制
Jul 15 Javascript
js将键值对字符串转为json字符串的方法
Mar 30 Javascript
vue使用keep-alive保持滚动条位置的实现方法
Apr 09 Javascript
Vue的状态管理vuex使用方法详解
Feb 05 Javascript
JS如何实现封装列表右滑动删除收藏按钮
Jul 23 Javascript
JS变量提升及函数提升实例解析
Sep 03 Javascript
javascript中attribute和property的区别详解
Jun 05 #Javascript
使用jquery实现的一个图片延迟加载插件(含图片延迟加载原理)
Jun 05 #Javascript
用js的document.write输出的广告无阻塞加载的方法
Jun 05 #Javascript
javascript数组去重方法终极总结
Jun 05 #Javascript
javascript设计模式之解释器模式详解
Jun 05 #Javascript
javascript监听鼠标滚轮事件浅析
Jun 05 #Javascript
详解JavaScript语法对{}处理的坑爹之处
Jun 05 #Javascript
You might like
全国FM电台频率大全 - 3 河北省
2020/03/11 无线电
深入理解PHP几个算法:PHP冒泡、PHP二分法、PHP求素数、PHP乘法表
2013/06/06 PHP
php操作xml
2013/10/27 PHP
easyui的tabs update正确用法分享
2014/03/21 PHP
thinkphp3.0输出重复两次的解决方法
2014/12/19 PHP
Laravel中unique和exists验证规则的优化详解
2018/01/28 PHP
js 在定义的时候立即执行的函数表达式(function)写法
2013/01/16 Javascript
Jquery和JS用外部变量获取Ajax返回的参数值的方法实例(超简单)
2013/06/17 Javascript
html dom节点操作(获取/修改/添加或删除)
2014/01/23 Javascript
jquery插件lazyload.js延迟加载图片的使用方法
2014/02/19 Javascript
使用微信内置浏览器点击下拉框出现页面乱跳转现象(iphone),该怎么办
2016/01/04 Javascript
判断输入的字符串是否是日期格式的简单方法
2016/07/11 Javascript
基于Vue的SPA动态修改页面title的方法(推荐)
2018/01/02 Javascript
详解JS实现简单的时分秒倒计时代码
2019/04/25 Javascript
Angular封装搜索框组件操作示例
2019/04/25 Javascript
layui动态渲染生成左侧3级菜单的方法(根据后台返回数据)
2019/09/23 Javascript
Vue实现购物车实例代码两则
2020/05/30 Javascript
[02:31]DOTA2帕克 英雄基础教程
2013/11/26 DOTA
[01:12]DOTA2次级职业联赛 - Newbee.Y 战队宣传片
2014/12/01 DOTA
python中的字典详细介绍
2014/09/18 Python
python测试驱动开发实例
2014/10/08 Python
python实现停车管理系统
2018/11/30 Python
Python3.5内置模块之time与datetime模块用法实例分析
2019/04/27 Python
django 解决扩展自带User表遇到的问题
2020/05/14 Python
Python 如何操作 SQLite 数据库
2020/08/17 Python
python语言time库和datetime库基本使用详解
2020/12/25 Python
美国主要的特色咖啡和茶公司:Peet’s Coffee
2020/02/14 全球购物
JavaScript获取当前url根目录(路径)
2014/02/19 面试题
军训生自我鉴定范文
2013/12/27 职场文书
投标担保书范文
2014/04/02 职场文书
小学生暑假家长评语
2014/04/17 职场文书
幼儿园秋季开学寄语
2014/08/02 职场文书
爱心捐助活动总结
2015/05/09 职场文书
叶问观后感
2015/06/15 职场文书
导游词之丽江普济寺
2019/10/22 职场文书
浅谈Nginx 中的两种限流方式
2021/03/31 Servers