模拟bind方法与unbind方法
jquery的bind() 方法为被选元素添加一个或多个事件处理程序,并规定事件发生时运行的函数。
模拟的bind事件主要是针对ie与w3c事件模型的不一致提供一个统一的接口。然后再设置绑定事件的上下文为触发事件的元素,也就是在事件中能够通过this访问到触发事件的元素。
unbind:移除掉绑定的方法。
trigger:触发某个事件:如$("#bt1").trigger("click") 则会触发id为bt1的点击事件
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; handle.funName=evt; 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){ if(handle.sour==fun&&handle.funName==evt){ if(x.removeEventListener){ x.removeEventListener(evt,handle,useCapture); } else if(x.detachEvent) { x.detachEvent('on'+evt,handle); } //移除掉了事件把对应的数组设置为null x.events[i]=null; } } } } else{ console.log("没有绑定任何事件"); } }) } _window.MQuery.fn.trigger=function(funName){ this.each(function(x){ //检查是否存在该方法 存在则调用 if(x[funName]){ x[funName](); } }) } })(window);
测试代码
比如绑定键盘点击事件以及键盘点击事件
<!DOCTYPE html> <html> <head> <title>mquery</title> <style> .p{ width: 50px; height: 50px; border: 1px solid #ddd; margin-bottom: 20px; padding: 20px; } </style> <script type="text/javascript" src="../core/sizzle.js"></script> <script type="text/javascript" src="../core/mquery.js"></script> <script type="text/javascript" src="../core/event.js"></script> </head> <body> <p class="p">ppppp1</p> <p class="p">ppppp2</p> <button onclick="bind()">bind</button> <button onclick="unbind()">unbind</button> <button onclick="trigger()">trigger click event</button> <script type="text/javascript"> var p = $("p"); function showMsg(e){ //console.log(this.innerHTML); console.log(e.keyCodeNames); console.log(e.buttons); } function click(e){ console.log("click: "+this.innerHTML); } function mouseover(e){ console.log("mouseover: "+this.innerHTML); } function bind(){ console.log("bind keydown and mousedown event"); p.bind("keydown",showMsg); p.bind("mousedown",showMsg); p.bind("click",click); p.bind("mouseover",mouseover); } function unbind(){ p.unbind("keydown",showMsg) p.unbind("mousedown",showMsg); p.unbind("click",click); p.unbind("mouseover",mouseover); console.log("unbind keydown and mousedown event"); } function trigger(){ p.trigger("click"); } </script> </body> </html>
如果点击了某个元素或者按了键盘某个键则会显示该元素的innerHTML,然后显示按了哪个键或者点击了鼠标哪个键。
源代码下载: