Thursday, October 1, 2009

JavaScript events handler

Today, with the growth of web based applications (and I'm talking about applications and not image galleries websites), more and more of the server side is shifting back to the client. Thus, more and more BL is done in the client.
JavaScript, similar to to Java, C, C++, C# and others is a full scale OO language. YES, it's an OO language. Everything you have in the class based OO languages, you have here. Among a lot of things, there is a need for events handling. Here is a conglomeration of an events util class that handles everything. It's written in JS and it's a cross platform script (meaning, it'll work on IE, FF, Chrome etc).

This code was gathered from the book "Professional JavaScript for Web Developers" written by Nicholas C. Zakas

var EventUtil = {

// var btn = document.getElementById("btn1");
// var handler = function() {
//     alert('hello');
// }
// EventUtil.addHandler(btn, "click", handler};
addHandler : function(element, type, handler) {
    if (element.addEventListener) {
        element.addEventListener(type, handler, false);
    } else if (element.attachEvent) {
        element.attachEvent("on" + type, handler);
    } else {
        element["on" + type] = handler;
    }
},

getEvent : function(event) {
    return event ? event : window.event;
},

getTarget : function(event) {
    return event.target || event.srcElement;
},

preventDefault : function(event) {
    if (event.preventDefault) {
        event.preventDefault();
    } else {
        event.returnValue = false;
    }
},

// EventUtil.addHandler(btn, "click", handler};
removeHandler : function(element, type, handler) {
    if (element.removeEventListener) {
        element.removeEventListener(type, handler, false);
    } else if (element.detachEvent) {
        element.detachEvent("on" + type, handler);
    } else {
        element["on" + type] = null;
    }
},

stopPropagation : function(event) {
    if (event.stopPropagation) {
        event.stopPropagation();
    } else {
        event.cancelBubble = true;
    }
}
}


On the same issue, sometimes you need to create your own types (for example message type) and you need to listen/fire it. Here is an example for a class dealing with this. This sample was taken from the same book as the above.


/*

//
// sample for using the custom handler firing
//
function handleMessage(event) {
alert("Message received: " + event.message);
}
// create a new object
var target = new EventTarget();
 
// add an event handler
target.addHandler("message", handleMessage);
 
// fire the event
target.fire({ type : "message", message : "hello...." });
 
// remove the handler
target.removeHandler("message", handleMessage);
*/

function EventTarget() {
   this.handlers = {};
}

EventTarget.prototype = {
   constructor : EventTarget,
   
   addHandler : function(type, handler) {
       if (typeof this.handlers[type] == "undefined") {
           this.handlers[type] = [];
       }
       
       this.handlers[type].push(handler);
   },
   
   fire : function(event) {
       if (!event.target) {
           event.target = this;
       }
       if (this.handlers[event.type] instanceof Array) {
           var handlers = this.handlers[event.type];
           for (var i = 0, len = handlers.length; i < len; i++) {
               handlers[i](event);
           }
       }
   },
   
   removeHandler : function(type, handler) {
       if (this.handlers[event.type] instanceof Array) {
           var handlers = this.handlers[event.type];
           for (var i = 0, len = handlers.length; i < len; i++) {
               if (handlers[i] == handler) {
                   break;
               }
           }
           
           handlers.splice(i, 1);
       }
   }
}