Stop The Window.Onload Madness

Madness - Image from DC Comics There are a lot cool javascript libraries floating around the Intarweb these days that add cool behavior to web pages. My favorites are the ones that you simply add to the head section of your website and control via markup. It is a great way to enhance structural html markup with Javascript.

Unfortunately many of these attempt to hijack the window.onload event. Ok, a show of hands (and I have been guilty of this as well). How many of you have written code like this to handle the onload event in javascript within a .js file?

function init()
{
}

window.onload = init;

Stop it!

That line of code will completely wipe out any other functions that were attached and ready to handle the onload event. How arrogant of your script to do so. Instead, your script should learn to play nicely.

Unfortunately, Javascript doesn’t support the delegate syntax that C# has. It’d be nice to be able to do this.

function init()
{
}

window.onload += init;

But that won’t work. One approach I found on Simon Incutio’s blog (which is used by the original LightboxJS script) involves using a method that safely attaches an event handling method to the onload event without overwriting existing event handlers.

It works by checking to see if there any methods are already attached to the event. If so it attaches a new anonymous method that calls the original method along with the method you are attempting to attach.

Here is a snippet demonstrating this technique.

function highlightXFNLinks()
{
  // Does stuff...
}

//
// Adds event to window.onload without overwriting currently 
// assigned onload functions.
function addLoadEvent(func)
{    
    var oldonload = window.onload;
    if (typeof window.onload != 'function')
    {
        window.onload = func;
    } 
    else 
    {
        window.onload = function()
        {
            oldonload();
            func();
        }
    }
}

addLoadEvent(highlightXFNLinks);

This is pretty nifty, but there appears to be a whole new school of script libraries that provide this sort of functionality for attaching to any event, not just the window.onload event.

I am sure you Javascript Gurus will expose how out of date and ignorant I am of this area (it is true) but the few that I have heard of that seem to be catching on like wildfire are the Prototype JavaScript Framework (often just referred to as prototype.js), the Dojo Toolkit, and Behaviour.

I will probably end up rewriting all my libraries to use one of these tooltips so that I stop duplicating code. Since each of my javascript libraries are stand-alone, I make sure to include the addLoadEvent method in each of them. But I think its time to allow a dependency on another script to avoid this duplication.

What others have said

Requesting Gravatar... Marcelo Calbucci Apr 06, 2006 12:56 PM
# re: Stop The Window.Onload Madness
Yes, there is a better way than that:

function AddOnload(myfunc)
{
if(window.addEventListener)
window.addEventListener('load', myfunc, false);
else if(window.attachEvent)
window.attachEvent('onload', myfunc);
}

Requesting Gravatar... Jeff Lewis Apr 06, 2006 1:59 PM
# re: Stop The Window.Onload Madness
Marcelo's version is the "best".

Prototype has abstractions for this and similar issues.

I'm writing an ASP.NET v1.1 app that makes heavy use of Prototype and I've been very happy with it.


Requesting Gravatar... Haacked Apr 06, 2006 2:16 PM
# re: Stop The Window.Onload Madness
Does that work in Safari and Firefox?
Requesting Gravatar... Jeff Lewis Apr 06, 2006 3:00 PM
# re: Stop The Window.Onload Madness
Yes, Prototype works in IE/Firefox/Safari
Requesting Gravatar... Haacked Apr 06, 2006 4:09 PM
# re: Stop The Window.Onload Madness
Sorry, I meant Marcelo's version.
Requesting Gravatar... Alex May 08, 2006 7:46 PM
# re: Stop The Window.Onload Madness
So does it?
Requesting Gravatar... Vincent Verbrugh Jun 15, 2006 7:22 AM
# re: Stop The Window.Onload Madness
here is an other and shorter solution:

if (window.onload) {
var func = window.onload;
window.onload = function() {
func();
startSlideShows();
}
} else {
window.onload = startSlideShows;
}
Requesting Gravatar... Myo Kyaw Htun Jul 17, 2007 2:28 AM
# re: Stop The Window.Onload Madness
I've been getting problem with "window.onload" for a long time ago. Now you solved it for me :). Really thanks.
Requesting Gravatar... TAD_UK Aug 22, 2007 3:07 PM
# re: Stop The Window.Onload Madness
function MultiOnLoad(f){var o=window.onload;window.onload=function(){o?o():o;f()}}


//the old way ;)
window.onload = function() {alert("onload!");}
//example :)
new MultiOnLoad(function() {alert('second');});
new MultiOnLoad(function() {alert('three');});
Requesting Gravatar... bsgu_drew Nov 05, 2007 9:24 AM
# re: Stop The Window.Onload Madness
// Prototype version
Event.observe(window, "load", some_function);
Requesting Gravatar... George Mar 22, 2008 11:55 AM
# re: Stop The Window.Onload Madness
Thanks,
Using Vincent Verbrugh's version OK in Opera.
Requesting Gravatar... Peter Postma May 08, 2008 2:05 PM
# re: Stop The Window.Onload Madness
This helps, but the problem I'm facing is most packaged software does not do that themselves. And their functions load last.

I had to give up and found 2 other ways to do it that work in most browsers:
setInterval:

function x() {
if(divexists) {
//perform ops
clearInterval(mytimer);
}
}
var mytimer = setInterval('x()', 250);


what I am finding is this runs only once in most versions of FF :-((

so I'm using this function for now:

function x() {
if(document.getElementById('...')) {
// do operations
} else {
//if we still dont have our DOM, wait and try again.
setTimeout('x()', 200);
}
}
setTimeout('x()', 500);


This effectively lets me run multiple window.onload operations without having to worry about what hijacks the onload method after my code is done. NOTE: you MUST use the quote marks in the setTimeout() call in the function!! This prevents the "too much recursion" error in F.F. by forcing the recursed function call to be evaluated by the browser each call.
Requesting Gravatar... danny Sep 01, 2008 6:45 PM
# re: Stop The Window.Onload Madness
i wrote something similar as well on how to handle multiple window events in javascript.

however, i've received similar feedback to use window.addEventListener and window.attachEvent but as far as i know, they're browser dependant functions and not part of the core javascript language.

if my assumption is true, wouldn't it be better to use non-browser dependant functions?

What do you have to say?

(will show your gravatar)
Please add 6 and 7 and type the answer here: