Javascript處理DOM元素事件實(shí)現(xiàn)代碼
更新時間:2012年05月23日 19:36:46 作者:
DOM元素都有一些標(biāo)準(zhǔn)事件,一般使用時只要使用onclick=function的方式就可以了,但是當(dāng)需要為DOM元素添加多個事件,刪除事件,或在用Javascript封裝控件的時候,為封裝的控件添加自定義事件的時候
DOM元素都有一些標(biāo)準(zhǔn)事件,一般使用時只要使用onclick=function的方式就可以了,但是當(dāng)需要為DOM元素添加多個事件,刪除事件,或在用Javascript封裝控件的時候,為封裝的控件添加自定義事件的時候,onclick=function的方式就不夠用了,但是瀏覽器有addEventListener和attachEvent方法可供調(diào)用,從而模擬出類似于C#中的事件委托的事件觸發(fā)機(jī)制!
/*
* 功能:事件處理
* Author:LQB
* 時間:2009-1-4
* #include JCore.js
*/
var JEvents = function(){
this.events={};
this.addEvent = function(o){//添加事件
if(typeof o == 'string'){/*strArg1,strArg2……的方式傳遞參數(shù)*/
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個參數(shù)開始
callArgs = typeof(callArgs)!="undefined"?callArgs:[];
var delegate = fn.createDelegate(callArgs,sp);//JCore支持
//為fn方法創(chuàng)建標(biāo)記,在刪除事件時使用
if(!fn.uid) {
var time = new Date();
fn.uid= ""+time.getMinutes()+time.getSeconds()+time.getMilliseconds();
}
//標(biāo)記委托,在刪除事件綁定時使用
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){//觸發(fā)事件
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++){//依次觸發(fā)所有方法
functions[i].apply(window,Arg);
}
}
}
/*---------------------------------------私有方法--------------------------------------*/
var getCacheAttName = function(eventName,fnuid){
return "handle-"+eventName+"-"+fnuid;
}
}
/*------------------------------------------------------以下是靜態(tài)方法,用于處理DOM element的事件-----------------------------------------*/
var JEventsExtendMethod = {
cache : {//時間處理緩存,用于標(biāo)記各個事件處理方法,在刪除事件時使用
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個參數(shù)開始
callArgs = typeof(callArgs)!="undefined"?callArgs:[];
var delegate = fn.createDelegate(callArgs,sp);//JCore支持
if (el.addEventListener){//Mozilla系列,按隊(duì)列順序執(zhí)行
el.addEventListener(enFX, delegate, false);//第三個參數(shù)與觸發(fā)方式相關(guān)
} else if (el.attachEvent){//非Mozilla系列,按堆棧順序執(zhí)行(后加的事件先執(zhí)行)
el.attachEvent(enIE, delegate);
}
//為fn方法創(chuàng)建標(biāo)記,在刪除事件時使用
if(!fn.uid) {
var time = new Date();
fn.uid= ""+time.getMinutes()+time.getSeconds()+time.getMilliseconds();
}
if(!el.id){
el.id = JCore.id(el,null);
}
//標(biāo)記委托,在刪除事件綁定時使用
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的參數(shù)包裝---------------------------------*/
var JEventWrap = function(event){
this.xtype="EventWrap";
this.data=null;
this.srcElement = null; //發(fā)生事件的文檔元素
this.button = null; //[FX:0-左鍵,1-中間鍵,2-右鍵][IE:1-左鍵,2-右鍵,4-中鍵](僅對onmousedown, onmouseup,onmousemove有效)
this.type = null;
this.clientX = 0; //鼠標(biāo)指針相對客戶區(qū)或?yàn)g覽器窗口的X坐標(biāo)(標(biāo)準(zhǔn)屬性)
this.clientY = 0; //鼠標(biāo)指針相對客戶區(qū)或?yàn)g覽器窗口的Y坐標(biāo)(標(biāo)準(zhǔn)屬性)
this.offsetX = 0; //鼠標(biāo)指針相對于源元素的X坐標(biāo)(兼容屬性)(IE)
this.offsetY = 0; //鼠標(biāo)指針相對于源元素的Y坐標(biāo)(兼容屬性)(IE)
this.screenX = 0; //鼠標(biāo)指針相對于用戶顯示器的左上角X坐標(biāo)(兼容屬性)(FX)
this.screenY = 0; //鼠標(biāo)指針相對于用戶顯示器的左上角Y坐標(biāo)(兼容屬性)(FX)
this.altKey = false; //是否Alt鍵
this.ctrlKey = false; //是否Ctrl鍵,
this.shitfKey = false; //是否Shift鍵
this.keyCode = 0;
this.originaEvent = null; //未包裝的原始事件對象
/*----構(gòu)造-----*/
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文件見上一篇日志:面向?qū)ο驤avascript核心支持代碼
復(fù)制代碼 代碼如下:
/*
* 功能:事件處理
* Author:LQB
* 時間:2009-1-4
* #include JCore.js
*/
var JEvents = function(){
this.events={};
this.addEvent = function(o){//添加事件
if(typeof o == 'string'){/*strArg1,strArg2……的方式傳遞參數(shù)*/
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個參數(shù)開始
callArgs = typeof(callArgs)!="undefined"?callArgs:[];
var delegate = fn.createDelegate(callArgs,sp);//JCore支持
//為fn方法創(chuàng)建標(biāo)記,在刪除事件時使用
if(!fn.uid) {
var time = new Date();
fn.uid= ""+time.getMinutes()+time.getSeconds()+time.getMilliseconds();
}
//標(biāo)記委托,在刪除事件綁定時使用
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){//觸發(fā)事件
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++){//依次觸發(fā)所有方法
functions[i].apply(window,Arg);
}
}
}
/*---------------------------------------私有方法--------------------------------------*/
var getCacheAttName = function(eventName,fnuid){
return "handle-"+eventName+"-"+fnuid;
}
}
/*------------------------------------------------------以下是靜態(tài)方法,用于處理DOM element的事件-----------------------------------------*/
var JEventsExtendMethod = {
cache : {//時間處理緩存,用于標(biāo)記各個事件處理方法,在刪除事件時使用
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個參數(shù)開始
callArgs = typeof(callArgs)!="undefined"?callArgs:[];
var delegate = fn.createDelegate(callArgs,sp);//JCore支持
if (el.addEventListener){//Mozilla系列,按隊(duì)列順序執(zhí)行
el.addEventListener(enFX, delegate, false);//第三個參數(shù)與觸發(fā)方式相關(guān)
} else if (el.attachEvent){//非Mozilla系列,按堆棧順序執(zhí)行(后加的事件先執(zhí)行)
el.attachEvent(enIE, delegate);
}
//為fn方法創(chuàng)建標(biāo)記,在刪除事件時使用
if(!fn.uid) {
var time = new Date();
fn.uid= ""+time.getMinutes()+time.getSeconds()+time.getMilliseconds();
}
if(!el.id){
el.id = JCore.id(el,null);
}
//標(biāo)記委托,在刪除事件綁定時使用
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的參數(shù)包裝---------------------------------*/
var JEventWrap = function(event){
this.xtype="EventWrap";
this.data=null;
this.srcElement = null; //發(fā)生事件的文檔元素
this.button = null; //[FX:0-左鍵,1-中間鍵,2-右鍵][IE:1-左鍵,2-右鍵,4-中鍵](僅對onmousedown, onmouseup,onmousemove有效)
this.type = null;
this.clientX = 0; //鼠標(biāo)指針相對客戶區(qū)或?yàn)g覽器窗口的X坐標(biāo)(標(biāo)準(zhǔn)屬性)
this.clientY = 0; //鼠標(biāo)指針相對客戶區(qū)或?yàn)g覽器窗口的Y坐標(biāo)(標(biāo)準(zhǔn)屬性)
this.offsetX = 0; //鼠標(biāo)指針相對于源元素的X坐標(biāo)(兼容屬性)(IE)
this.offsetY = 0; //鼠標(biāo)指針相對于源元素的Y坐標(biāo)(兼容屬性)(IE)
this.screenX = 0; //鼠標(biāo)指針相對于用戶顯示器的左上角X坐標(biāo)(兼容屬性)(FX)
this.screenY = 0; //鼠標(biāo)指針相對于用戶顯示器的左上角Y坐標(biāo)(兼容屬性)(FX)
this.altKey = false; //是否Alt鍵
this.ctrlKey = false; //是否Ctrl鍵,
this.shitfKey = false; //是否Shift鍵
this.keyCode = 0;
this.originaEvent = null; //未包裝的原始事件對象
/*----構(gòu)造-----*/
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文件見上一篇日志:面向?qū)ο驤avascript核心支持代碼
您可能感興趣的文章:
- 一些主流JS框架中DOMReady事件的實(shí)現(xiàn)小結(jié)
- JavaScript DOM 添加事件
- JS中dom0級事件和dom2級事件的區(qū)別介紹
- Javascript Event事件中IE與標(biāo)準(zhǔn)DOM的比較
- javascript 刪除dom對象的事件函數(shù)代碼
- 關(guān)于javascript DOM事件模型的兩件事
- JavaScript DOM事件(筆記)
- 談?wù)勎覍avaScript DOM事件的理解
- 深入理解JS DOM事件機(jī)制
- 理解javascript中DOM事件
- JS DOMReady事件的六種實(shí)現(xiàn)方法總結(jié)
- javascript事件捕獲機(jī)制【深入分析IE和DOM中的事件模型】
- Javascript DOM事件操作小結(jié)(監(jiān)聽鼠標(biāo)點(diǎn)擊、釋放,懸停、離開等)
相關(guān)文章
JavaScript 程序循環(huán)結(jié)構(gòu)詳解
這篇文章主要為大家介紹了JavaScript 程序循環(huán)結(jié)構(gòu),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2021-12-12Javascript如何判斷數(shù)據(jù)類型和數(shù)組類型
這篇文章主要介紹Javascript如何判斷數(shù)據(jù)類型和數(shù)組類型,通俗易懂,需要的朋友可以參考下。2016-06-06用javascript動態(tài)調(diào)整iframe高度的代碼
用javascript動態(tài)調(diào)整iframe高度的代碼...2007-04-04javascript實(shí)現(xiàn)獲取cookie過期時間的變通方法
這篇文章主要介紹了javascript實(shí)現(xiàn)獲取cookie過期時間的變通方法,因?yàn)閏ookie過期時間是由瀏覽器控制的,所以想獲取過期時間只能通過本文的變通方法來實(shí)現(xiàn),需要的朋友可以參考下2014-08-08不用AI也能實(shí)現(xiàn)的文字自動播報(SpeechSynthesis文本實(shí)例合成)
SpeechSynthesis是HTML5的一個新特性,基于SpeechSynthesis可以實(shí)現(xiàn)在客戶瀏覽器端進(jìn)行動態(tài)文本的語音合成播放,這篇文章主要介紹了不用AI也能實(shí)現(xiàn)的文字自動播報(SpeechSynthesis文本實(shí)例合成),需要的朋友可以參考下2023-03-03javascript定義變量時帶var與不帶var的區(qū)別分析
這篇文章主要介紹了javascript定義變量時帶var與不帶var的區(qū)別,以一個簡單實(shí)例分析了變量定義時帶var與不帶var的執(zhí)行原理及用法區(qū)別,需要的朋友可以參考下2015-01-01js實(shí)現(xiàn)購物車加減和價格運(yùn)算
這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)購物車加減和價格運(yùn)算,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-08-08