建站学 - 轻松建站从此开始!

建站学-个人建站指南,网页制作,网站设计,网站制作教程

解析Javascript事件模块的演变(3)

时间:2011-04-09 13:49来源: 作者: 点击:
本文我们将继续讲解事件模块的演变,在上一篇解析Javascript事件模块的演变(2) 中的add有个问题,对同一类型事件添加多个hanlder时,IE6/7/8下会无序,如 01
 

本文我们将继续讲解事件模块的演变,在上一篇解析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 }();

 

相关:

IE6/7/8下同类型事件的多个handler无序执行

(责任编辑:admin)
织梦二维码生成器
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片