模拟bind方法与unbind方法
jquery的bind() 方法为被选元素添加一个或多个事件处理程序,并规定事件发生时运行的函数。
模拟的bind事件主要是针对ie与w3c事件模型的不一致提供一个统一的接口。然后再设置绑定事件的上下文为触发事件的元素,也就是在事件中能够通过this访问到触发事件的元素。
event.js代码
/*!Event 事件处理 模拟jquery的bind与unbind * *Date 2014-4-10 *author meng */ (function(_window){ _window.MQuery.fn.bind=function(evt,fun,useCapture){ //定义handle统一处理回调事件 handle封装事件默认的e参数,针对IE与标准的不同实现提供一个统一接口。 var handle=function(e){ var evt=e||_window.event; //检查是否是w3c模式 var isW3c=evt.toString&&evt.toString().indexOf("MouseEvent")!=-1; //封装e 兼容w3c模式与ie模式 var evtArg={}; for(var p in evt){ evtArg[p]=evt[p]; } evtArg.target=evt.target||evt.srcElement; //阻止事件默认行为 evtArg.preventDefault=function(){ if(evt.preventDefault){ evt.preventDefault(); } else{ evt.returnValue =false; } } //停止事件冒泡 evtArg.stopPropagation=function(){ if(evt.stopPropagation){ evt.stopPropagation(); } else{ evt.cancelBubble=true; } } //判断鼠标点击事件点击了(左、中、右)哪个键 //w3c与ie都使用button代表点击的哪个键 //w3c:0左键 1中键 2右键 //IE:0没有按键 1左键 2中键 3同时按下左右键 4中键 5同时按下左中键 6同时按下右中键 7同时按下左中右键 var buttons={ "left":false, "middle":false, "right":false } if(isW3c){ //W3c switch(event.button){ case 0:buttons.left=true;break; case 1:buttons.middle=true;break; case 2:buttons.right=true;break; default:break; } } else if(event.button){ //Ie switch(event.button){ case 1:buttons.left=true;break; case 2:buttons.right=true;break; case 3:buttons.left=true;buttons.right=true;break; case 4:buttons.middle=true;break; case 5:buttons.left=true;buttons.middle=true;break; case 6:buttons.middle=true;buttons.right=true;break; case 7:buttons.left=true;buttons.middle=true;buttons.right=true;break; default:break; } } evtArg.buttons=buttons; //判断键盘点击事件,w3c与ie均提供了keycode获取按键的代码 通过string.fromCharCode方法获取具体的键盘字母值 //同时检查是否按了ctrl、shift、alt。 //把按键值存入keycodenames属性 evtArg.keyCodeNames=evt.keyCode?[String.fromCharCode(evt.keyCode)]:[]; if(evt.altKey){ evtArg.keyCodeNames.push(‘ALT‘); } if(evt.shiftKey){ evtArg.keyCodeNames.push(‘SHIFT‘); } if(evt.ctrlKey){ evtArg.keyCodeNames.push(‘CTRL‘); } //获取默认的参数e evtArg.get=function(){ return evt; } //获取事件触发元素 //通过fun的call调用设置触发元素为事件的上下文 fun.call(evtArg.target,evtArg); } //把原函数设置为handle的一个属性,这样移除事件的时候通过原函数找到handle,才能移除 handle.sour=fun; useCapture=useCapture||false; //绑定事件 this.each(function(x){ if(!x.events){ x.events=[]; } x.events.push(handle); if(x.addEventListener){ x.addEventListener(evt,handle,useCapture); console.log(‘w3c‘); } else if(x.attachEvent) { x.attachEvent(‘on‘+evt,handle); console.log(‘ie‘); } }) } _window.$.fn.unbind=function(evt,fun,useCapture){ useCapture=useCapture||false; this.each(function(x){ //x.events不为undefined才移除事件 if(x.events){ for(var i=0;i<x.events.length;i++){ var handle=x.events[i]; if(handle.sour==fun){ if(x.removeEventListener){ x.removeEventListener(evt,handle,useCapture); } else if(x.detachEvent) { x.detachEvent(‘on‘+evt,handle); } } } } else{ console.log("没有绑定任何事件"); } }) } })(window);
测试代码
比如绑定键盘点击事件以及键盘点击事件
function showMsg(e){
console.log(this.innerHTML); console.log(e.keyCodeNames); console.log(e.buttons); } function bind(){ $(document).bind("keydown",showMsg); $(document).bind("mousedown",showMsg); } function unbind(){ $(document).unbind("keydown",showMsg) $(document).unbind("mousedown",showMsg); }
如果点击了某个元素或者按了键盘某个键则会显示该元素的innerHTML,然后显示按了哪个键或者点击了鼠标哪个键。
源代码下载: