本文我们将继续讲解事件模块的演变,在上一篇解析Javascript事件模块的演变(2) 中的add有个问题,对同一类型事件添加多个hanlder时,IE6/7/8下会无序,如 01 <div id="d1" style="width:200px;height:200px;background:gold;"></div> 02 <script type="text/javascript"> 03 var el = document.getElementById('d1'); 04 function handler1(){alert('1');} 05 function handler2(){alert('2');} 06 function handler3(){alert('3');} 07 function handler4(){alert('4');} 08 function handler5(){alert('5');} 09 E.add(el, 'click', handler1); 10 E.add(el, 'click', handler2); 11 E.add(el, 'click', handler3); 12 E.add(el, 'click', handler4); 13 E.add(el, 'click', handler5); 14 </script> IE9/Firefox/Safari/Chomre/Opera会依次输出1,2,3,4,5。但IE6/7/8中则不一定。为解决所有浏览器中多个事件handler有序执行,我们需要一个队列来管理所有的handler。
这次,把所有的内部细节封装在一个匿名函数中,该函数执行完毕后返回如上一篇接口相同的方法。另外 1,把真正的事件handler挂在el上,即el.listeners,其为一个对象,每一个类型的事件为一个数组,如click为el.listeners["click"] = []。 2,所有的handler存在在对于的数组中 3,删除一个hanlder,将从数组中将其删除 01 E = function(){ 02 function _isEmptyObj(obj){ 03 for(var a in obj){ 04 return false; 05 } 06 return true; 07 } 08 function _each(ary, callback){ 09 for(var i=0,len=ary.length; i<len;){ 10 callback(i, ary[i]) ? i=0 : i++; 11 } 12 } 13 function _remove(el, type){ 14 var handler = el.listeners[type]['_handler_']; 15 el.removeEventListener ? 16 el.removeEventListener(type, handler, false) : 17 el.detachEvent('on'+type, handler); 18 delete el.listeners[type]; 19 if(_isEmptyObj(el.listeners)){ 20 delete el.listeners; 21 } 22 } 23 // 添加事件 24 function add(el, type, fn){ 25 el.listeners = el.listeners || {}; 26 var listeners = el.listeners[type] = el.listeners[type] || []; 27 listeners.push(fn); 28 if(!listeners['_handler_']){ 29 listeners['_handler_'] = function(e){ 30 var evt = e || window.event; 31 for(var i=0,fn; fn=listeners[i++];){ 32 fn.call(el, evt); 33 } 34 } 35 el.addEventListener ? 36 el.addEventListener(type, listeners['_handler_'], false) : 37 el.attachEvent('on' + type, listeners['_handler_']); 38 } 39 } 40 // 删除事件 41 function remove(el, type, fn){ 42 if(!el.listeners) return; 43 var listeners = el.listeners && el.listeners[type]; 44 if(listeners) { 45 _each(listeners, function(i, f){ 46 if(f==fn){ 47 return listeners.splice(i, 1); 48 } 49 }); 50 if(listeners.length == 0){ 51 _remove(el,type); 52 } 53 } 54 } 55 //主动触发事件 56 function dispatch(el ,type){ 57 try{ 58 if(el.dispatchEvent){ 59 var evt = document.createEvent('Event'); 60 evt.initEvent(type,true,true); 61 el.dispatchEvent(evt); 62 }else if(el.fireEvent){ 63 el.fireEvent('on'+type); 64 } 65 }catch(e){}; 66 } 67 return { 68 add: add, 69 remove: remove, 70 dispatch: dispatch 71 }; 72 }();
相关: (责任编辑:admin) |