Posted in Javascript onMay 23, 2012
DOM元素都有一些标准事件,一般使用时只要使用onclick=function的方式就可以了,但是当需要为DOM元素添加多个事件,删除事件,或在用Javascript封装控件的时候,为封装的控件添加自定义事件的时候,onclick=function的方式就不够用了,但是浏览器有addEventListener和attachEvent方法可供调用,从而模拟出类似于C#中的事件委托的事件触发机制!
/* * 功能:事件处理 * Author:LQB * 时间:2009-1-4 * #include JCore.js */ var JEvents = function(){ this.events={}; this.addEvent = function(o){//添加事件 if(typeof o == 'string'){/*strArg1,strArg2……的方式传递参数*/ for(var i = 0, a = arguments, v; v = a[i]; i++){ v = v.toString().toLowerCase(); var enFX = v.indexOf("on")==0 ? v.substr(2) : v; if(!this.events[enFX]){ this.events[enFX] = true; } } }else{ JCore.apply(this.events, o,false); } }; this.addListener = function(eventName,fn,scope/*,Args……*/){//为事件添加处理方法 if(typeof(eventName)!="string"|| eventName.lenght==0)return; if(typeof(fn)!="function")return; eventName = eventName.toString().toLowerCase(); var enFX = eventName.indexOf("on")==0 ? eventName.substr(2) : eventName; if(!this.events[enFX]){ throw "Error! Event /"" + eName + "/" doesnt exist." } var sp = scope||window; var callArgs = Array.prototype.slice.call(arguments, 3);//从第4个参数开始 callArgs = typeof(callArgs)!="undefined"?callArgs:[]; var delegate = fn.createDelegate(callArgs,sp);//JCore支持 //为fn方法创建标记,在删除事件时使用 if(!fn.uid) { var time = new Date(); fn.uid= ""+time.getMinutes()+time.getSeconds()+time.getMilliseconds(); } //标记委托,在删除事件绑定时使用 delegate.uid = getCacheAttName(enFX,fn.uid); if(typeof(this.events[enFX])!="object") this.events[enFX]=[]; this.events[enFX].push(delegate);//把方法添加到事件列表中 }; this.removeListener = function(eventName,fn){//移除事件绑定 if(eventName && fn){ eventName = eventName.toString().toLowerCase(); var enFX = eventName.indexOf("on")==0?eventName.substr(2):eventName; var AttName = getCacheAttName(enFX,fn.uid); if(typeof(this.events[enFX])=="object"){//存在这个事件 var functions = this.events[enFX]; for(i=0;i<functions.length;i++){//依次查找每个方法 if(functions[i].uid===AttName){//找到,删除 this.events[enFX].remove(functions[i]); break; } } } } } this.fireEvent = function(eName,eventArg){//触发事件 eName = eName.toString().toLowerCase(); var enFX = eName.indexOf("on")==0 ? eName.substr(2) : eName; var Arg = new Array(); if(typeof(eventArg)!="undefined"){ if(typeof(eventArg)=="array") Arg=eventArg; else Arg.push(eventArg); } if(typeof(this.events[enFX])=="object"){//存在此事件,同时添加了事件处理方法 var functions = this.events[enFX]; for(i=0;i<functions.length;i++){//依次触发所有方法 functions[i].apply(window,Arg); } } } /*---------------------------------------私有方法--------------------------------------*/ var getCacheAttName = function(eventName,fnuid){ return "handle-"+eventName+"-"+fnuid; } } /*------------------------------------------------------以下是静态方法,用于处理DOM element的事件-----------------------------------------*/ var JEventsExtendMethod = { cache : {//时间处理缓存,用于标记各个事件处理方法,在删除事件时使用 eventCache : {}, setCache : function(el,Name,value){ if(typeof(this.eventCache[el])!="object"){ this.eventCache[el]={length :1}; } this.eventCache[el][Name]=value; this.eventCache[el].length++; }, getCache : function(el,Name){ if(typeof(this.eventCache[el]) =="object") return this.eventCache[el][Name]; else return null; }, removeCache : function(el,Name){ if(typeof(this.eventCache[el]) =="object"){ delete this.eventCache[el][Name];//删除属性 this.eventCache[el].length--; } if(this.eventCache[el] && this.eventCache[el].length ==1)//清除 delete this.eventCache[el]; } }, getCacheAttName : function(eventName,fnuid){ return "handle-"+eventName+"-"+fnuid; }, bind : function(el,eventName,fn,scope/*,Args……*/){//为elment添加事件处理方法 if(typeof(el)=="undefined"||el==null)return; if(typeof(eventName)!="string"|| eventName.lenght==0)return; if(typeof(fn)!="function")return; var indexOfon = eventName.toString().toLowerCase().indexOf("on"); var enIE = indexOfon==0?eventName:"on"+eventName; var enFX = indexOfon==0?eventName.substr(2):eventName; var sp = scope||window; var callArgs = Array.prototype.slice.call(arguments, 4);//从第5个参数开始 callArgs = typeof(callArgs)!="undefined"?callArgs:[]; var delegate = fn.createDelegate(callArgs,sp);//JCore支持 if (el.addEventListener){//Mozilla系列,按队列顺序执行 el.addEventListener(enFX, delegate, false);//第三个参数与触发方式相关 } else if (el.attachEvent){//非Mozilla系列,按堆栈顺序执行(后加的事件先执行) el.attachEvent(enIE, delegate); } //为fn方法创建标记,在删除事件时使用 if(!fn.uid) { var time = new Date(); fn.uid= ""+time.getMinutes()+time.getSeconds()+time.getMilliseconds(); } if(!el.id){ el.id = JCore.id(el,null); } //标记委托,在删除事件绑定时使用 var AttName = this.getCacheAttName(enFX,fn.uid); this.cache.setCache(el.id,AttName,delegate); }, unbind : function(el,eventName,fn){//为elment解除事件绑定 if(typeof(el)=="undefined"||el==null)return; var indexOfon = eventName.toString().toLowerCase().indexOf("on"); var enIE = indexOfon==0?eventName:"on"+eventName; var enFX = indexOfon==0?eventName.substr(2):eventName; var AttName = this.getCacheAttName(enFX,fn.uid); var delegate = this.cache.getCache(el.id,AttName); if(delegate){ if (el.removeEventListener){//Mozilla系列 el.removeEventListener(enFX, delegate, false); } else if (el.detachEvent){//非Mozilla系列 el.detachEvent(enIE, delegate); } } //删除事件缓存 this.cache.removeCache(el.id,AttName); } } JCore.apply(JEvents,JEventsExtendMethod); /*--------------------------------对event的参数包装---------------------------------*/ var JEventWrap = function(event){ this.xtype="EventWrap"; this.data=null; this.srcElement = null; //发生事件的文档元素 this.button = null; //[FX:0-左键,1-中间键,2-右键][IE:1-左键,2-右键,4-中键](仅对onmousedown, onmouseup,onmousemove有效) this.type = null; this.clientX = 0; //鼠标指针相对客户区或浏览器窗口的X坐标(标准属性) this.clientY = 0; //鼠标指针相对客户区或浏览器窗口的Y坐标(标准属性) this.offsetX = 0; //鼠标指针相对于源元素的X坐标(兼容属性)(IE) this.offsetY = 0; //鼠标指针相对于源元素的Y坐标(兼容属性)(IE) this.screenX = 0; //鼠标指针相对于用户显示器的左上角X坐标(兼容属性)(FX) this.screenY = 0; //鼠标指针相对于用户显示器的左上角Y坐标(兼容属性)(FX) this.altKey = false; //是否Alt键 this.ctrlKey = false; //是否Ctrl键, this.shitfKey = false; //是否Shift键 this.keyCode = 0; this.originaEvent = null; //未包装的原始事件对象 /*----构造-----*/ if(event){ if(event.srcElement){//IE this.srcElement = event.srcElement; this.offsetX = event.offsetX; this.offsetY = event.offsetY; this.button = event.button; } else{ this.srcElement = event.target; this.offsetX = event.clientX - event.target.offsetLeft; this.offsetY = event.clientY - event.target.offsetTop; } this.type = event.type; this.altKey = event.altKey; this.ctrlKey = event.ctrlKey; this.shitfKey = event.shitfKey; this.clientX = event.clientX; this.clientY = event.clientY; this.screenX = event.screenX; this.screenY = event.screenY; this.keyCode = event.keyCode; this.originaEvent = event; } }
其中JCore.js文件见上一篇日志:面向对象Javascript核心支持代码
Javascript处理DOM元素事件实现代码
声明:登载此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述。
Reply on: @reply_date@
@reply_contents@