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在IE7下无法使用 $.ajax解决方法
Nov 11 Javascript
js获取通过ajax返回的map型的JSONArray的方法
Jan 09 Javascript
JS实现点击事件统计的简单实例
Jul 10 Javascript
angularjs实现下拉列表的选中事件示例
Mar 03 Javascript
js 倒计时(高效率服务器时间同步)
Sep 12 Javascript
微信小程序中post方法与get方法的封装
Sep 26 Javascript
微信小程序6位或多位验证码密码输入框功能的实现代码
May 29 Javascript
JavaScript Math对象和调试程序的方法分析
May 13 Javascript
13 个npm 快速开发技巧(推荐)
Jul 04 Javascript
js实现的格式化数字和金额功能简单示例
Jul 30 Javascript
jquery 回调操作实例分析【回调成功与回调失败的情况】
Sep 27 jQuery
JS数组及对象遍历方法代码汇总
Jun 16 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
PHP+MySQL 手工注入语句大全 推荐
2009/10/30 PHP
在PHP中养成7个面向对象的好习惯
2010/01/28 PHP
基于ubuntu下nginx+php+mysql安装配置的具体操作步骤
2013/04/28 PHP
PHP捕获Fatal error错误的方法
2014/06/11 PHP
PHP文件操作之获取目录下文件与计算相对路径的方法
2016/01/08 PHP
php处理带有中文URL的方法
2016/07/11 PHP
Laravel实现ORM带条件搜索分页
2019/10/24 PHP
jquery 问答知识整理
2010/02/11 Javascript
菜鸟学习JavaScript小实验之函数引用
2010/11/17 Javascript
input标签内容改变的触发事件介绍
2014/06/18 Javascript
jquery 插件实现多行文本框[textarea]自动高度
2015/03/04 Javascript
JS判断当前页面是否在微信浏览器打开的方法
2015/12/08 Javascript
jQuery中 $ 符号的冲突问题及解决方案
2016/11/04 Javascript
js 将input框中的输入自动转化成半角大写(税号输入框)
2017/02/16 Javascript
js插件实现图片滑动验证码
2020/09/29 Javascript
vue实现学生录入系统之添加删除功能
2018/07/11 Javascript
浅谈小程序 setData学问多
2019/02/20 Javascript
VUE+elementui面包屑实现动态路由详解
2019/11/04 Javascript
jQuery实现小火箭返回顶部特效
2020/02/03 jQuery
[01:18:36]LGD vs VP Supermajor 败者组决赛 BO3 第一场 6.10
2018/07/04 DOTA
对于Python编程中一些重用与缩减的建议
2015/04/14 Python
利用Python命令行传递实例化对象的方法
2016/11/02 Python
python队列通信:rabbitMQ的使用(实例讲解)
2017/12/22 Python
python多环境切换及pyenv使用过程详解
2019/09/27 Python
使用Python实现牛顿法求极值
2020/02/10 Python
Django获取model中的字段名和字段的verbose_name方式
2020/05/19 Python
sublime3之内网安装python插件Anaconda的流程
2020/11/10 Python
Pycharm创建文件时自动生成文件头注释(自定义设置作者日期)
2020/11/24 Python
python爬虫scrapy框架之增量式爬虫的示例代码
2021/02/26 Python
Html5实现移动端、PC端 刮刮卡效果
2016/06/30 HTML / CSS
印度最好的在线药品订购网站:PharmEasy
2018/11/30 全球购物
Java的类可以定义为Protected或者Private得吗
2015/09/25 面试题
教学督导岗位职责
2015/04/10 职场文书
小程序后台PHP版本部署运行 LNMP+WNMP
2021/04/01 Servers
python3 删除所有自定义变量的操作
2021/04/08 Python
Redis特殊数据类型HyperLogLog基数统计算法讲解
2022/06/01 Redis