How to handle multiple window events in Javascript

I’ve written a window event handler mainly for handling multiple onload events. The typical way of handling multiple onload events is by creating a helper function that contains all the onload functions and using window.onload to call the helper function.

An example would look something like this,

function onloader()
{
    onload1();
    onload2();
    // and so on...
}
window.onload = onloader;

However, I wanted to write something more object oriented and more elegant. So I wrote my own method which will allow you to add multiple events to the window object. This script is very early in its stage and only allows you to add events. I will probably work on it more if I figure out more uses for it.

So here’s the script.

/**
 *	@author:	Danny Ng (https://www.dannyism.com)
 *	@date:		30/08/08
 *	@notes:		Free to use and distribute without altering this notice. Would appreciate a link back.
 */
 
/**
 *	Window Events:
 *		- onblur
 *		- onerror
 *		- onfocus
 *		- onload
 *		- onresize
 *		- onunload
 *
 *	@usage: window.addEvent(event_type, function)
 *	@params: string, function
 */
function addEvent (e, func)
{
	var old_event;
	switch(e)
	{
		case 'onblur':
			old_event = this.onblur;
			if (typeof this.onblur == 'undefined')
			{
				this.onblur = function(e) {
					func();
				};
			}
			else if (typeof this.onblur == 'function')
			{
				this.onblur = function(e) {
					old_event();
					func();
				};
			}
			break;
		case 'onerror':
			old_event = this.onerror;
			if (typeof this.onerror == 'undefined')
			{
				this.onerror = function(e) {
					func();
				};
			}
			else if (typeof this.onerror == 'function')
			{
				this.onerror = function(e) {
					old_event();
					func();
				};
			}
			break;
		case 'onfocus':
			old_event = this.onfocus;
			if (typeof this.onfocus == 'undefined')
			{
				this.onfocus = function(e) {
					func();
				};
			}
			else if (typeof this.onfocus == 'function')
			{
				this.onfocus = function(e) {
					old_event();
					func();
				};
			}
			break;
		case 'onload':
			old_event = this.onload;
			if (typeof this.onload == 'undefined')
			{
				this.onload = function(e) {
					func();
				};
			}
			else if (typeof this.onload == 'function')
			{
				this.onload = function(e) {
					old_event();
					func();
				};
			}
			break;
		case 'onresize':
			old_event = this.onresize;
			if (typeof this.onresize == 'undefined')
			{
				this.onresize = function(e) {
					func();
				};
			}
			else if (typeof this.onresize == 'function')
			{
				this.onresize = function(e) {
					old_event();
					func();
				};
			}
			break;
		case 'onunload':
			old_event = this.onunload;
			if (typeof this.onunload == 'undefined')
			{
				this.onunload = function(e) {
					func();
				};
			}
			else if (typeof this.onunload == 'function')
			{
				this.onunload = function(e) {
					old_event();
					func();
				};
			}
			break;			
		default:
	}
}

I use this feature in my previous post in tracking exit links in Google Analytics where I need to handle multiple onload events as my other WordPress plugins uses the onload event as well.

An example of using this would be, window.addEvent(‘onload’, dtalk_ga.applyVirtualExits). Hope this helps.

[update date=01/09/08]
Thanks to ahot’s tip, I’ve shortened the code significantly now. Theoretically, this function should be able to work on all objects that support events.

/**
 *	@author:	Danny Ng (https://www.dannyism.com)
 *	@date:		01/09/08
 *	@notes:		Free to use and distribute without altering this notice. Would appreciate a link back.
 */
 
/**
 *	@pre-condition: object must support events
 *	@usage: object.addEvent(event_type, function)
 *	@params: string, function
 */
function addEvent(e, func)
{
	var old_event = this[e];
	if (old_event)
	{
		this[e] = function(e) {
			old_event();
			func();
		};
	}
	else
		this[e] = func();
}

[/update]

4 Comments on "How to handle multiple window events in Javascript"


  1. hmm, i’m not too convinced that it is entirely useless as those methods are part of the browser and not the language itself. so although it may work on FF, Opera and IE, these methods may not necessarily work on other browsers.

    it’s meant to be a helper function that should “theoretically” work on all browsers as it does not depend on any browser in-built functions. i haven’t tested it extensively yet and most likely won’t go through all the trouble of doing so.

    thanks for the info though. i couldn’t find those browser defined methods as i usually go to w3schools.com javascript/dom reference page but i found what you were talking about at http://www.javascriptkit.com/domref/windowmethods.shtml.

    Reply

  2. Actually any JavaScript object-properties/methods can be accessed in that way.
    E.g:
    document.body.style is equal to document.body[“style”] or document[“body”][“style”]
    Thus making window.onload=func is equal to window[“onload”]=func

    Anyway. Your function is useless :). JavaScript provides the same ability.
    Try this script:
    [code]
    function onload1() {alert(1);}
    function onload2() {alert(2);}

    window.onload = onload1;
    window.addEventListener(“load”, onload2, false); //this line works in FF&Opera, use attachEvent for IE
    [/code]
    You don’t need any js-framework to make it work. :)

    Reply

  3. oh wow, you are right. i didn’t know the window object uses an array of events. i will update the code when i get the time.

    do you mean the built-in methods like the ones found in prototype and other famous js frameworks? yes, i think they’re awesome. i used prototype, and scriptaculous a lot for my undergrad treatise.

    Reply

  4. Why so many cases? ) It was simpler to use something like:
    function addEvent (e, func)
    {
    old_event = this[e];
    if (old_event) this[e] = function(e) { old_event(); func(); };
    else this[e] = func;
    }

    BTW:
    What do you think about buildin methods:
    elem.addEventListener(…);
    elem.attachEvent(…);

    :)))

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *