• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
睫毛
博客园    首页    新随笔    联系   管理    订阅  订阅
javascript事件绑定封装

引用来自:http://www.cnblogs.com/yupeng/archive/2012/03/15/2395316.html

本质:不同的库或者工具中总是封装了不同的事件绑定形式,但是究其根源,还是IE事件模型和W3C事件模型不同的处理方式

1)W3C事件模型:支持事件捕捉和冒泡 addEventListener('type',function(){},bool) removeEventListener ('type',function(){},bool)

2)IE事件模型:仅支持事件冒泡 attachEvent('type',function(){}); detachEvent('type',fucntion(){});

*如何统一:设置W3C事件绑定函数的第三个参数为false,那么就不支持事件捕捉了。 

*原生的绑定形式:

obj.addEventListener('type',function(){},false);

obj.attachEvent('type',function(){});

*是否有注意的:

当然有,IE对同一个事件绑定2次会重复绑定2次,但是W3C只会绑定一次,会忽略后面的一个事件。这个要特别注意,特别是在开发的时候

在处理事件绑定顺序的问题上,参考了jquery的事件绑定原理,写出了一个自己用的简单的框架,解决了以下几个问题:

1. 修正IE下先绑定的事件后执行的BUG,统一为先绑定先执行的原则。

2. 支持自定义this指针.

3. 重复绑定的还没有完善,等完善后我会更新本代码。

4. 事件委托还没有放进来,和重复绑定一起解决完后放进来。

5. 代码中用到的navigator.isFirefox是自己补充的函数,因为里面处理的东西多,代码长,所以没有放上来,用的话,自己写一个简单的浏览器判断,很容易的....

View Code
  1 var jm = {};
  2     jm.Contains = function(a, b){        
  3             try{
  4                 return a.contains ? a != b && a.contains(b) : !!(a.compareDocumentPosition(b) & 16);
  5             }catch(e){}        
  6       };
  7     jm.eventTarget = function(e){
  8         return e.target || e.srcElement;
  9     };
 10     //get event's relatedTarget
 11     jm.relatedTarget = function(e){
 12         var element = null;
 13         if(e.type === "mouseover"){
 14             element = e.relatedTarget || e.fromElement;
 15         } else if(e.type === "mouseout"){
 16             element = e.relatedTarget || e.toElement;
 17         }
 18         return element;
 19     };
 20 (function(){
 21     var cacheEvent = {        
 22         /*
 23         elementId : {
 24             "click": [{fun: function(){}, scope: null }],
 25             "clickListener" : function(){},
 26             "mouseover" : [{fun: function(){}, scope: null }],
 27             "mouseoverListener" : function(){}
 28         },
 29         */    
 30         uuid : 0
 31     };  
 32     var addEvent = function(oElm, eType, handler){        
 33         if(document.addEventListener){    
 34             oElm.addEventListener(eType, handler, false);
 35         } else if(document.attachEvent){
 36             oElm.attachEvent("on" + eType,handler);
 37         }
 38     };
 39     var removeEvent = function(elm, eType, handler){
 40         if(document.removeEventListener){
 41             elm.removeEventListener(eType,handler, false);
 42         } else if(document.detachEvent){
 43             elm.detachEvent("on" + eType, handler);
 44         }
 45     }
 46     var addCache = function(oElm, eType, handler, scope){        
 47         var cacheKey = oElm.eventId;
 48         var scope = arguments.length > 3 ? scope : oElm;
 49         var handleItem = {"fun": handler, "scope": scope};
 50         if(!cacheKey){        
 51             oElm.eventId = "cache" + new Date().getTime() + "_" + (cacheEvent.uuid++);        
 52             cacheKey = oElm.eventId;
 53         }
 54         if(!cacheEvent[cacheKey]){
 55             cacheEvent[cacheKey] = {};
 56         }
 57         var newEtype = eType;
 58         switch(eType){
 59             case "mouseenter":
 60             case "mouseleave":
 61                 newEtype = eType === "mouseenter" ? "mouseover" : "mouseout";
 62                 var mouseEnterOrLeave = function(e){
 63                     var related = jm.relatedTarget(e);
 64                     if (!((related !== oElm) && (!jm.Contains(oElm, related)))) {
 65                         return false;
 66                     }
 67                     return true;
 68                 };                    
 69                                 
 70                 break;
 71             case 'mousewheel':
 72                 newEtype = navigator.isFirefox ? 'DOMMouseScroll' : 'mousewheel';                            
 73                 var mouseWheel = function(e){
 74                     var wheel = 'wheelDelta' in e ? -e.wheelDelta : e.detail || 0;
 75                     if(!e.wheelUp){
 76                         e.wheelUp = wheel < 0;
 77                     }
 78                     if(!e.wheelDown){
 79                         e.wheelDown = wheel > 0;
 80                     }    
 81                 };        
 82                     
 83                 break;
 84         }
 85 
 86         if(!cacheEvent[cacheKey][eType]){    //寻找click,mouseover等事件对应的函数对列
 87             cacheEvent[cacheKey][eType] = [handleItem];    
 88             var funQuery = cacheEvent[cacheKey][eType];
 89             var listener = function(e){        
 90                 if(mouseEnterOrLeave){
 91                     if(!mouseEnterOrLeave(e)){
 92                         return;
 93                     }
 94                 }
 95                 if(mouseWheel){
 96                     mouseEnterOrLeave(e);
 97                 }    
 98                 
 99                 var tempHandler;
100                 for(var i = 0,l = funQuery.length; i < l; i ++){
101                     tempHandler = funQuery[i];
102                     tempHandler.fun.call(tempHandler.scope, e);
103                 }
104             };
105             cacheEvent[cacheKey][eType + "Listener"] = listener;
106             addEvent(oElm, newEtype, listener);            
107         } else {
108             cacheEvent[cacheKey][eType].push(handleItem);
109         }
110     };
111     var removeCache = function(oElm, eType, handler){
112         var cacheKey = oElm.eventId;        
113         
114         if(!cacheKey || !cacheEvent[cacheKey]){        
115             return;
116         }
117         
118         var newEvtType = eType;
119         switch(eType){
120             case "mouseenter":
121             case "mouseleave":
122                 newEvtType = eType === "mouseenter" ? "mouseover" : "mouseout";            
123                 break;
124             case 'mousewheel':
125                 newEvtType = navigator.isFirefox ? 'DOMMouseScroll' : 'mousewheel';                                                
126                 break;
127         }
128         
129         var funQuery = cacheEvent[cacheKey][eType];
130         if(!funQuery){    //寻找click,mouseover等事件对应的函数对列
131             return;        
132         }
133         if(arguments.length < 3 || !handler){
134             removeEvent(oElm, newEvtType, cacheEvent[cacheKey][eType + "Listener"]);
135             delete cacheEvent[cacheKey][eType];
136             delete cacheEvent[cacheKey][eType + "Listener"];
137             return;
138         }
139         var i = 0;
140         while(funQuery[i]){
141             if(funQuery[i].fun === handler){
142                 funQuery.splice(i, 1);        
143                 break;
144             }
145             i ++;
146         }        
147     };
148     jm.bind = addCache;
149     jm.unbind = removeCache;
150 })();
151 
152 //实例调用
153 var btn = document.getElementById("btn");
154 var a = {
155     a: function(){  console.log(this.b);  }, 
156     b: "this is a下面的b"
157 };
158 var clickHandler = function(){
159     alert("this is click event");
160 };
161 jm.bind(btn, "click", a.a, a);
162 
163 jm.bind(btn, "click", clickHandler);
164 jm.bind(btn, "mouseenter", function(){console.log("enter");});
165 jm.bind(btn, "mouseleave", function(){console.log("leave");});
166 jm.bind(btn, "mousewheel", function(){console.log("mousewheel");});
167 var unbindBtn = document.getElementById("unbindBtn");
168 jm.bind(unbindBtn, "click", function(){
169     jm.unbind(btn, "click", clickHandler);
170     jm.unbind(btn, "mouseenter");
171     jm.unbind(btn, "mouseleave");
172 });

参考:http://stylechen.com/easyevent.html

posted on 2012-07-20 13:45  睫毛  阅读(413)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3