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 相关文章推荐
jQuery中的常用事件总结
Dec 27 Javascript
JSQL 批量图片切换的实现代码
May 05 Javascript
js获取IP地址的方法小结
Jul 01 Javascript
基于JavaScript实现单选框下拉菜单添加文件效果
Jun 26 Javascript
JavaScript轮播图简单制作方法
Feb 20 Javascript
js实现图片粘贴上传到服务器并展示的实例
Nov 08 Javascript
Vue中自定义全局组件的实现方法
Dec 08 Javascript
vue使用$emit时,父组件无法监听到子组件的事件实例
Feb 26 Javascript
vue源码解析之事件机制原理
Apr 21 Javascript
微信小程序自定义toast的实现代码
Nov 16 Javascript
JS前端模块化原理与实现方法详解
Mar 17 Javascript
微信小程序国际化探索实现(附源码地址)
May 20 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
造就帕卡马拉的帕卡斯是怎么被发现的
2021/03/03 咖啡文化
PHP获取MSN好友列表类的实现代码
2013/06/23 PHP
php生成复杂验证码(倾斜,正弦干扰线,黏贴,旋转)
2018/03/12 PHP
ThinkPHP框架实现导出excel数据的方法示例【基于PHPExcel】
2018/05/12 PHP
Thinkphp5.0框架使用模型Model的获取器、修改器、软删除数据操作示例
2019/10/11 PHP
Alliance vs AM BO3 第一场2.13
2021/03/10 DOTA
js css样式操作代码(批量操作)
2009/10/09 Javascript
cnblogs中在闪存中屏蔽某人的实现代码
2010/11/14 Javascript
用innerhtml提高页面打开速度的方法
2013/08/02 Javascript
JS根据年月获得当月天数的实现代码
2014/07/03 Javascript
基于jQuery实现的文字按钮表单特效整理
2014/12/07 Javascript
解决JS请求服务器gbk文件乱码的问题
2015/10/16 Javascript
JS实现太极旋转思路分析
2016/12/09 Javascript
ES6学习之变量的两种命名方法示例
2017/07/18 Javascript
vue环境搭建简单教程
2017/11/07 Javascript
小程序自定义组件实现城市选择功能
2018/07/18 Javascript
Echart折线图手柄触发事件示例详解
2018/12/16 Javascript
JavaScript交换两个变量方法实例
2019/11/25 Javascript
VUE table表格动态添加一列数据,新增的这些数据不可以编辑(v-model绑定的数据不能实时更新)
2020/04/03 Javascript
[09:59]DOTA2-DPC中国联赛2月7日Recap集锦
2021/03/11 DOTA
python3处理含有中文的url方法
2018/05/10 Python
Django分页查询并返回jsons数据(中文乱码解决方法)
2018/08/02 Python
opencv python 图像去噪的实现方法
2018/08/31 Python
详解Python with/as使用说明
2018/12/13 Python
Python完全识别验证码自动登录实例详解
2019/11/24 Python
如何解决cmd运行python提示不是内部命令
2020/07/01 Python
Omio意大利:全欧洲低价大巴、火车和航班搜索和比价
2017/12/02 全球购物
欧洲最古老的鞋厂:Peter Kaiser
2019/11/05 全球购物
构造方法和其他方法的区别
2016/04/26 面试题
学生请假条格式
2014/04/11 职场文书
综合办公室主任岗位职责
2014/04/13 职场文书
教师个人查摆剖析材料
2014/10/14 职场文书
党员教师群众路线思想汇报范文
2014/10/28 职场文书
营销与策划实训报告
2014/11/05 职场文书
心得体会该怎么写呢?
2019/06/27 职场文书
numpy array找出符合条件的数并赋值的示例代码
2022/06/01 Python