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 相关文章推荐
一个对于js this关键字的问题
Jan 09 Javascript
javascript新手语法小结
Jun 15 Javascript
新老版本juqery获取radio对象的方法
Mar 01 Javascript
javascript for循环从入门到偏门(效率优化+奇特用法)
Aug 01 Javascript
jquery的ajax请求全面了解
Mar 20 Javascript
js 通过cookie实现刷新不变化树形菜单
Oct 30 Javascript
jquery+css3实现网页背景花瓣随机飘落特效
Aug 17 Javascript
javascript中call apply 与 bind方法详解
Mar 10 Javascript
AngularJS入门教程之多视图切换用法示例
Nov 02 Javascript
Vue 短信验证码组件开发详解
Feb 14 Javascript
jquery点赞功能实现代码 点个赞吧!
May 29 jQuery
jQuery实现右侧抽屉式在线客服功能
Dec 25 jQuery
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设计模式 Facade(外观模式)
2011/06/26 PHP
php提示无法加载或mcrypt没有找到 PHP 扩展 mbstring解决办法
2012/03/27 PHP
利用php递归实现无限分类 格式化数组的详解
2013/06/08 PHP
解析PHP中$_FILES的使用以及注意事项
2013/07/05 PHP
PHP 中魔术常量的实例详解
2017/10/26 PHP
thinkPHP3.2.2框架行为扩展及demo示例
2018/06/19 PHP
window.open的功能全解析
2006/10/10 Javascript
类似框架的js代码
2006/11/09 Javascript
jQuery之ajax技术的详细介绍
2013/06/19 Javascript
js Map List 遍历使用示例
2013/07/10 Javascript
jQuery产品间断向下滚动效果核心代码
2014/05/08 Javascript
牛叉的Jquery——Jquery与DOM对象的互相转换及DOM的三种操作
2015/10/29 Javascript
简要了解jQuery移动web开发的响应式布局设计
2015/12/04 Javascript
iscroll.js的上拉下拉刷新时无法回弹的解决方法
2016/02/18 Javascript
Vue.js 父子组件通讯开发实例
2016/09/06 Javascript
实例解析jQuery工具函数
2016/12/01 Javascript
基于Vue实现拖拽功能
2020/07/29 Javascript
layer的prompt弹出框,点击回车,触发确定事件的方法
2019/09/06 Javascript
跟老齐学Python之变量和参数
2014/10/10 Python
在Python中使用next()方法操作文件的教程
2015/05/24 Python
Windows下搭建python开发环境详细步骤
2020/07/20 Python
Python实现获取命令行输出结果的方法
2017/06/10 Python
Python程序员面试题 你必须提前准备!(答案及解析)
2018/01/23 Python
PyTorch上搭建简单神经网络实现回归和分类的示例
2018/04/28 Python
Django+Ajax+jQuery实现网页动态更新的实例
2018/05/28 Python
安装python及pycharm的教程图解
2019/10/10 Python
基于pandas中expand的作用详解
2019/12/17 Python
python构造函数init实例方法解析
2020/01/19 Python
python 使用递归回溯完美解决八皇后的问题
2020/02/26 Python
django 数据库返回queryset实现封装为字典
2020/05/19 Python
将时尚融入珠宝:Adornmonde
2019/10/17 全球购物
群众路线教育实践活动个人对照检查材料
2014/09/22 职场文书
预备党员期盼十八届四中全会召开思想汇报
2014/10/17 职场文书
2015年教师教学工作总结
2015/04/28 职场文书
蔬果开业典礼发言稿应该怎么写?
2019/09/03 职场文书
nginx中封禁ip和允许内网ip访问的实现示例
2022/03/17 Servers