Thursday, January 21, 2010

Javascript Event with Multiple Callback handlers

Javascript, by default, doesn't provide the attachment of multiple callback handlers with the events of the DOM elements, like onclick, onmove etc. The following delegate class gives this facility and makes it very easy to register multiple callbacks for a single event.

The possible use is as follows,

globalDelegate.addEventHandler(domElementRef,"event name", function(args){// function implementation 1 here;},args1); 

globalDelegate.addEventHandler(domElementRef,"event name", function(args){// function implementation 2 here;},args2); 


The class is given as follows, just place this code in some js file and include that in your webpage. You can use the globalDelegate object to add multiple event handlers for any DOMElement's event. I hope it will solve the problems of many who are looking for multiple function calls for a single event. Some people may argue that we can also do it like domEle.onclick = function(){A();B();C();}, but this is static implementation. You can add any number of such functions dynamically based on some condition to be called on a certain event. That's the difference. So enjoy dudes. Please leave the comment if you feel any problem.

function FunctionObject(handler,args){
this.func = handler;
this.args = args;
}
function Delegate(){
this.handlers = [];
this.count = 0;
this.addEventHandler = function(element,evnt,handler,args){
var callbacks = this.handlers[element+"_"+evnt];
if(typeof(callbacks) == "undefined"){
this.handlers[element+"_"+evnt] = [new FunctionObject(handler,args)];
this.count++;
}
else if(typeof(callbacks) == "object"){
var len = callbacks.length;
callbacks[len] = new FunctionObject(handler,args);
}
this.attachEventWithElement(element,evnt);
}
this.clear = function(){
this.handlers = [];
this.count = 0;
}
this.Delegate = function(element,evnt){
var handler = this.handlers[element+"_"+evnt];
for(i=0;i
var funcObj = handler[i];
var func = funcObj.func;
var args = funcObj.args;
func(args);
}
}
this.attachEventWithElement=function(element,evnt){

var elm = Element.getElement(element);
if(elm == null)return;
switch(evnt){
case "mouseover":
elm.onmouseover = function(){globalDelegate.Delegate(element,evnt)};break;
case "mouseout":
elm.onmouseout = function(){globalDelegate.Delegate(element,evnt)};break;
case "mousedown":
elm.onmousdown = this.Delegate(element,evnt);break;
case "mouseup":
elm.onmouseup = this.Delegate(element,evnt);break;
case "mousemove":
elm.onmousemove = this.Delegate(element,evnt);break;
case "keyup":
elm.onkeyup = this.Delegate(element,evnt);break;
case "keydown":
elm.onkeydown = this.Delegate(element,evnt);break;
case "keypress":
elm.onkeypress = this.Delegate(element,evnt);break;
case "click":
elm.onclick = this.Delegate(element,evnt);break;
case "focus":
elm.onfocus = this.Delegate(element,evnt);break;
case "change":
elm.onchange = this.Delegate(element,evnt);break;
case "load":
elm.onload = this.Delegate(element,evnt);break;
case "dblclick":
elm.ondblclick = this.Delegate(element,evnt);break;
}
}
}
var globalDelegate = new Delegate();