DOM elements have some standard events. Generally, you only need to use onclick=function. However, when you need to add multiple events to DOM elements, delete events, or use Javascript to encapsulate controls, add When customizing events, the onclick=function method is not enough, but the browser has addEventListener and attachEvent methods to call, thus simulating an event triggering mechanism similar to event delegation in C#!
/*
* Function: Event processing
* Author: LQB
* Time: 2009-1-4
* #include JCore.js
*/
var JEvents = function(){
this.events={};
this.addEvent = function(o){//Add event
if(typeof o == 'string'){/* Pass parameters in the form of 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……*/){//Add a processing method for the event
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);//Starting from the 4th parameter
callArgs = typeof(callArgs)!="undefined"?callArgs :[];
var delegate = fn.createDelegate(callArgs,sp);//JCore supports
//Create a mark for the fn method and use
if(!fn.uid) { when deleting an event
var time = new Date();
fn.uid= "" time.getMinutes() time.getSeconds() time.getMilliseconds();
}
//Mark delegate, delete When binding events, use
delegate.uid = getCacheAttName(enFX,fn.uid);
if(typeof(this.events[enFX])!="object")
this.events[enFX] =[];
this.events[enFX].push(delegate);//Add the method to the event list
};
this.removeListener = function(eventName,fn){//Move Except event binding
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"){//This event exists
var functions = this.events[enFX];
for(i=0;iif(functions[i].uid===AttName ){//Find, delete
this.events[enFX].remove(functions[i]);
break;
}
}
}
}
}
this.fireEvent = function(eName,eventArg){//Trigger event
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"){//This event exists and is added at the same time Event handling method
var functions = this.events[enFX];
for(i=0;ifunctions[i].apply (window,Arg);
}
}
}
/*-------------------------- ------------Private method------------------------------------ --*/
var getCacheAttName = function(eventName,fnuid){
return "handle-" eventName "-" fnuid;
}
}
/*------ --------------------------------------------------------The following is Static method, used to handle DOM element events------------------------------------------------ -*/
var JEventsExtendMethod = {
cache : {//Time processing cache, used to mark each event processing method, used when deleting events
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];//Delete attribute
this.eventCache[el ].length--;
}
if(this.eventCache[el] && this.eventCache[el].length ==1)//Clear
delete this.eventCache[el];
}
},
getCacheAttName : function(eventName,fnuid){
return "handle-" eventName "-" fnuid;
},
bind : function(el,eventName,fn ,scope/*,Args……*/){//Add event handling method for element
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); //Start from the 5th parameter
callArgs = typeof(callArgs)!="undefined"?callArgs:[];
var delegate = fn.createDelegate(callArgs,sp);//JCore supports
if (el.addEventListener){//Mozilla series, executed in queue order
el.addEventListener(enFX, delegate, false);// The third parameter is related to the triggering method
} else if (el.attachEvent){//Non-Mozilla series, executed in stack order (events added later are executed first)
el.attachEvent(enIE, delegate);
}
//Create a tag for the fn method and use it when deleting the event. " time.getMinutes() time.getSeconds() time.getMilliseconds();
}
if(!el.id){
el.id = JCore.id(el,null);
}
//Mark delegate, use when deleting event bindings
var AttName = this.getCacheAttName(enFX,fn.uid);
this.cache.setCache(el.id,AttName,delegate );
},
unbind : function(el,eventName,fn){//Unbind event for element
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 series
el.removeEventListener(enFX, delegate, false);
} else if (el.detachEvent){//non Mozilla series
el.detachEvent(enIE, delegate);
}
}
//Delete event cache
this.cache.removeCache(el.id,AttName);
}
}
JCore.apply(JEvents,JEventsExtendMethod);
/*-------------------------------- ---Parameter wrapper for event---------------------------------*/
var JEventWrap = function (event){
this.xtype="EventWrap";
this.data=null;
this.srcElement = null; //The document element where the event occurred
this.button = null; / /[FX:0-left button, 1-middle button, 2-right button][IE:1-left button, 2-right button, 4-middle button] (Only valid for onmousedown, onmouseup, onmousemove)
this. type = null;
this.clientX = 0; //The X coordinate of the mouse pointer relative to the client area or browser window (standard attribute)
this.clientY = 0; //The mouse pointer relative to the client area or browser Y coordinate of the window (standard attribute)
this.offsetX = 0; //X coordinate of the mouse pointer relative to the source element (compatible attribute) (IE)
this.offsetY = 0; //Mouse pointer relative to Y coordinate of the source element (compatibility attribute) (IE)
this.screenX = 0; //X coordinate of the mouse pointer relative to the upper left corner of the user's display (compatibility attribute) (FX)
this.screenY = 0; //The Y coordinate of the mouse pointer relative to the upper left corner of the user's display (compatibility attribute) (FX)
this.altKey = false; //Whether the Alt key
this.ctrlKey = false; //Whether the Ctrl key,
this.shitfKey = false; //Whether the Shift key
this.keyCode = 0;
this.originaEvent = null; //Unwrapped original event object
/*----Construction- ----*/
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;
}
}
See the previous blog for the JCore.js file:
Object-oriented Javascript core support code