源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

自己封装的javascript事件队列函数版

  • 时间:2020-11-28 20:06 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:自己封装的javascript事件队列函数版
[b]背景[/b] javascript中使用addEventListener()或attachEvent()绑定事件时会有几个小问题: 一、使用addEventListener()或attachEvent()添加的匿名函数无法移除。
[u]复制代码[/u] 代码如下:
var oBtn = document.getElementById('btn'); oBtn.addEventListener('click',function(){     alert('button is clicked') },false) oBtn.reomveEventListener('click',function(){     alert('button is clicked') },false) //oBtn上的事件无法移除,因为传入的是一个匿名函数
二、ie6-ie8中,使用attachEvent()绑定多个事件的倒序执行问题。
[u]复制代码[/u] 代码如下:
var oBtn = document.getElementById('btn'); oBtn.attachEvent('onclick',function(){     alert(1) }) oBtn.attachEvent('onclick',function(){     alert(2) }) oBtn.attachEvent('onclick',function(){     alert(3) }) //ie9+   下执行顺序1、2、3 //ie6-ie8下执行顺序3、2、1
[b]解决问题[/b] 我想写一个跨浏览器的事件绑定模块,这样以后可以复用,同时我想解决上诉问题。JQuery内部使用事件队列和数据缓存机制解决此问题,看了下相关源码,实在复杂,自个试了一些方法,勉强实现。贴段代码,原来是用面向对象写的,不想让人看得很复杂,所有改成函数来组织。
[u]复制代码[/u] 代码如下:
/*绑定事件的接口  *  *@param    {dom-DOM}和{type-string}和{fn-function}  可选参数{fnName-string}  *@execute  创建事件队列,添加到DOM对象属性上,             将事件处理程序(函数)加入事件队列             可为事件处理程序添加一个标识符,用于删除指定事件处理程序   */  function bind(dom,type,fn,fnName){     dom.eventQueue = dom.eventQueue || {};     dom.eventQueue[type] = dom.eventQueue[type] || {};     dom.handler = dom.handler || {};     if (!fnName) {         var index = queueLength(dom,type);         dom.eventQueue[type]['fnQueue'+index] = fn;     }     else {         dom.eventQueue[type][fnName] = fn;     };     if (!dom.handler[type]) bindEvent(dom,type); }; /*绑定事件  *  *@param    {dom-DOM}和{type-string}  *@execute  只绑定一次事件,handler用于遍历执行事件队列中的事件处理程序(函数)  *@caller   bind()  */ function bindEvent(dom,type){     dom.handler[type] = function(){         for(var guid in dom.eventQueue[type]){             dom.eventQueue[type][guid].call(dom);         }     };     if (window.addEventListener) {         dom.addEventListener(type,dom.handler[type],false);     }     else {         dom.attachEvent('on'+type,dom.handler[type]);     }; }; /*移除事件的接口  *  *@param    {dom-DOM}和{type-string} 可选参数{fnName-function}  *@execute  如果没有标识符,则执行unBindEvent()             如果有标识符,则删除指定事件处理程序,如果事件队列长度为0,执行unBindEvent()   */ function unBind(dom,type,fnName){     var hasQueue = dom.eventQueue && dom.eventQueue[type];     if (!hasQueue) return;     if (!fnName) {         unBindEvent(dom,type)     }     else {         delete dom.eventQueue[type][fnName];         if (queueLength(dom,type) == 0) unBindEvent(dom,type);     }; }; /*移除事件  *  *@param    {dom-DOM}和{type-string}  *@execute  移除绑定的事件处理程序handler,并清空事件队列  *@caller   unBind()  */ function unBindEvent(dom,type){     if (window.removeEventListener) {         dom.removeEventListener(type,dom.handler[type])     }     else {         dom.detachEvent(type,dom.handler[type])     }     delete dom.eventQueue[type]; }; /*判断事件队列长度  *  *@param    {dom-DOM}和{type-string}  *@caller   bind() unBind()  */ function queueLength(dom,type){     var index = 0;     for (var length in dom.eventQueue[type]){         index++ ;     }     return index; };
[b]使用方法[/b]
[u]复制代码[/u] 代码如下:
var oBtn = document.getElementById('btn'); //绑定事件 //为button同时绑定三个click事件函数 //ie6-ie8下执行顺序不变 bind(oBtn,'click',function(){     alert(1); }) bind(oBtn,'click',function(){     alert(2); },'myFn') bind(oBtn,'click',function(){     alert(3); }) //移除事件 //移除所有绑定的click事件函数,支持移除匿名函数 unBind(oBtn,'click') //只移除标识符为myfn的事件函数 unBind(oBtn,'click','myFn')
[b]程序思路[/b] 程序主要思路就像将事件队列作为dom元素对象的一个属性,添加在dom元素上,而不会污染全局环境,这样可以解决不同dom元素绑定不同事件类型的多个事件函数的数据存储问题。
[u]复制代码[/u] 代码如下:
//dom元素上的事件队列 dom{     eventQueue : {         'click' : {             fnQueue1 : function,             myfn     : function,             fnQueue3 : function         }         'mouseover' : {             fnQueue1 : function,             fnQueue2 : function         }     } }
每次先把事件函数添加到对应事件类型的事件队列中,只绑定一次事件。触发事件时执行handler事件函数,handler则遍历执行事件队列中的事件函数。 unBind()如果没有传入标识符,则移除所有绑定的事件函数,支持移除匿名函数,如果有标识符则移除指定的事件函数。 程序逻辑并不复杂,可能有bug和性能问题,有兴趣可以指导交流下。
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部