Coding with Jesse

addDOMLoadEvent

June 21st, 2006

Update March 2014: This code is now available on GitHub

There has been a problem with using window.onload in JavaScript. This event handler waits until all the images and other files load before executing. If you need some JavaScript to execute when the page loads, you usually only need the HTML to be downloaded, not all the images.

The event to use for this is "DOMContentLoaded", but only Firefox (and recently, Opera 9) support this. There are different ways to do this in every other browser, and people have been working on finding a complete solution to this for some time.

Very recently, this problem has been solved by Dean Edwards, Matthias Miller and John Resig. There is a unique solution for Internet Explorer, Safari, and for W3C-compatible browsers (Firefox and Opera 9).

Very soon after, Dan Webb adapted the solution to prototype. Unlike the original solution, this code allows you to add more than one function to be executed when the DOM loads.

Inspired by Simon Willison's addLoadEvent function, I wanted to create a standalone generic solution that anyone could use without needing a specific framework.

So here's the js file: adddomloadevent.js, and here's the actual code:

/*
 * (c)2006 Jesse Skinner/Dean Edwards/Matthias Miller/John Resig
 * Special thanks to Dan Webb's domready.js Prototype extension
 * and Simon Willison's addLoadEvent
 *
 * For more info, see:
 * http://www.thefutureoftheweb.com/blog/adddomloadevent
 * http://dean.edwards.name/weblog/2006/06/again/
 * http://www.vivabit.com/bollocks/2006/06/21/a-dom-ready-extension-for-prototype
 * http://simon.incutio.com/archive/2004/05/26/addLoadEvent
 * 
 *
 * To use: call addDOMLoadEvent one or more times with functions, ie:
 *
 *    function something() {
 *       // do something
 *    }
 *    addDOMLoadEvent(something);
 *
 *    addDOMLoadEvent(function() {
 *        // do other stuff
 *    });
 *
 */
 
addDOMLoadEvent = (function(){
    // create event function stack
    var load_events = [],
        load_timer,
        script,
        done,
        exec,
        old_onload,
        init = function () {
            done = true;

            // kill the timer
            clearInterval(load_timer);

            // execute each function in the stack in the order they were added
            while (exec = load_events.shift())
                exec();

            if (script) script.onreadystatechange = '';
        };

    return function (func) {
        // if the init function was already ran, just run this function now and stop
        if (done) return func();

        if (!load_events[0]) {
            // for Mozilla/Opera9
            if (document.addEventListener)
                document.addEventListener("DOMContentLoaded", init, false);

            // for Internet Explorer
            /*@cc_on @*/
            /*@if (@_win32)
                document.write("<script id=__ie_onload defer src=//0><\/scr"+"ipt>");
                script = document.getElementById("__ie_onload");
                script.onreadystatechange = function() {
                    if (this.readyState == "complete")
                        init(); // call the onload handler
                };
            /*@end @*/

            // for Safari
            if (/WebKit/i.test(navigator.userAgent)) { // sniff
                load_timer = setInterval(function() {
                    if (/loaded|complete/.test(document.readyState))
                        init(); // call the onload handler
                }, 10);
            }

            // for other browsers set the window.onload, but also execute the old window.onload
            old_onload = window.onload;
            window.onload = function() {
                init();
                if (old_onload) old_onload();
            };
        }

        load_events.push(func);
    }
})();

Update: I added a demo page, as well as a compressed version (only 876 bytes).

Update: Thanks to Adam Schlag's suggestion, I fixed the memory leak in IE.

Update: Thanks again to Rob Cherny and Alistair Potts, I've updated the solution so that it works over HTTPS without any security issues. I also decreased the compressed size to 761 bytes. Now it's perfect! (I hope!)

Update: I've gone back and reworked the code to get rid of the global variables, and I've managed to reduce the compressed size to 563 bytes!

Update [Aug. 19, 2007]: Now the script preserves any existing window.onload function, and also executes functions instantly when called after the page has already loaded. But now the compressed version is a hefty 617 bytes.


Comments

1 . Francis Rowland on June 22nd, 2006

Francis Rowland

Hi Jesse

Nice addition. I like the use of conditional commenting.
I followed your link from Simon Willison's addLoadEvent page. I have implemented your addDOMLoadEvent code, and it works fine... er... but with a new error.

Actually, my guess is that this error (thrown by both IE and Firefox, but again without affecting functionality) might be the same as "func is not a function", which occurs with Simon's code.

So now I am getting:
Error: window.__load_events[i] is not a function

Any ideas?
huh... perhaps it doesn't matter.

vielen Danke
Francis

2 . Jesse Skinner on June 22nd, 2006

Jesse Skinner

Could it be that you're calling addDOMLoadEvent() with something other than a function? The code simply adds the parameter to a stack each time you call it, then executes each element like:

window.__load_events[i]();

so one of the things on the stack must not be a function.

3 . rob on June 22nd, 2006

rob

Jesse, thanks for posting this version, and thanks for the pointer from my site. I do like the ability to call it multiple times and the more I think about it the more I think I'll probably add it to my Object Literal version.

http://www.cherny.com/webdev/24/domloaded-script

I'm a big fan of trying to avoid variable collisions, etc. so Objects appeal to me.

4 . Jesse Skinner on June 22nd, 2006

Jesse Skinner

@rob - Thanks. I'm actually a fan of using objects for namespaces too on bigger projects. I'm looking forward to seeing your update.

5 . Ross on June 22nd, 2006

Ross

Hi Jesse,

I also did an extension for prototype :) which allowed multiple onloads.

In IE you only one "<scr"+"ipt id=__ie_onload .." needs to be added to the dom - once thats done you should be fine to run the init() for anyother functions via the timer similar to the safari / khtml method.

Like:

window.__load_timer = setInterval(function() {
var script = document.getElementById("__ie_onload");
if (/loaded|complete/.test(script.readyState)) {
init(); // call the onload handler
}
}, 10);

Ross

6 . Francis on June 26th, 2006

Francis

@Jesse

I tracked down the error. *phew*
I was trying to pass arguments to a funtion thus:

function something() {
// do something
}
addDOMLoadEvent(something(arguments));

Once I removed those arguments, and introduced them to my function in a different way, everything worked fine.

Thanks again for this code.

Francis

7 . Jesse Skinner on June 26th, 2006

Jesse Skinner

@Francis - Ah, yeah. That makes sense.

To do what you wanted to do, you can also write:

addDOMLoadEvent(function () {
something(arguments);
});

8 . Tanny O'Haley on June 28th, 2006

Tanny O'Haley

@Francis,

If you haven't already, you might want to try using an anonymous function.

function something(a, ...) {
// do something
}

addDOMLoadEvent(function() {
something(arguments);
});

9 . Francis on June 30th, 2006

Francis

@Jesse and @Tanny

It's all looking good now.
Thank you both for the pointer... that's done the trick.
I was going through things too fast, and not paying attention to one little function.

That was the spanner in the works!

Anyway, you can see this nice bit of code in action (albeit, behind-the-scenes!) at http://www.ukbms.org/


cheers

10 . Francis on June 30th, 2006

Francis

@Jesse and @Tanny

It's all looking good now.
Thank you both for the pointer... that's done the trick.
I was going through things too fast, and not paying attention to one little function.

That was the spanner in the works!

Anyway, you can see this nice bit of code in action (albeit, behind-the-scenes!) at http://www.ukbms.org/


cheers

11 . Rob Cherny on July 3rd, 2006

Rob Cherny

Guys, I've updated my Object Literal version to address the following:

- allows multiple calls
- also (sorta) resolves the IE/HTTPS issue

Let me know what you think.

http://www.cherny.com/webdev/26/domloaded-object-literal-updated

12 . digitaljhelms on July 7th, 2006

digitaljhelms

Just a little note that might help someone else out:

In some of my interface related external scripts that I reuse quite often, I have window.onload calls to which I wanted to implement the addDOMLoadEvent in place of.

However, to keep my js code modular and independantly functioning without regards to another external script, I went through and updated my script library to conditionally use the addDOMLoadEvent function if it is available during excecution.

So, instead of the last line in an external interface script being something like:

window.onload = function() { foo(); }

I've updated the line to use:

/* using addDOMLoadEvent? */
if (typeof addDOMLoadEvent != "undefined") {
addDOMLoadEvent(foo);
} else {
window.onload = function() {
foo();
}
}

Then to use the addDOMLoadEvent function, I just ensure that addDOMLoadEvent.js is included in my page source before any other external scripts. If its not, the onload function of the external scripts will function without addDOMLoadEvent as expected.

13 . Rob Madole on August 9th, 2006

Rob Madole

Can anyone comment on why the WebKit test looks for either 'loaded' or 'complete'? Why not just use one or the other?

14 . Adam Schlag on August 16th, 2006

Adam Schlag

I've been playing with this script for a few days, and decided I would test for any leaks in another script I was writing along side (a slightly modified version of) addDOMLoadEvent, and noticed that the IE "script.onreadystatechange = function()" closure was causing a leak. It can be cleaned up by adding this when __load_events is set to null:

window.__load_events = null;
// clean up the __ie_onload event
/*@cc_on @*/
/*@if (@_win32)
document.getElementById("__ie_onload").onreadystatechange = "";
/*@end @*/

In fact, you could eliminate the conditional javascript (and creating the extra script element with document.write) by using the following in place of the conditional js:

if (document.attachEvent)
document.attachEvent('onreadystatechange', init);

And then at the beginning of the init function, do this:

// If IE, only run this when ready state is "complete"
if (document.readyState && document.readyState != "complete") return;

If you find anything wrong with this, feel free to correct it, but I have not noticed any ill effects so far. :)

15 . James Peter on August 16th, 2006

James Peter

Hi. In this moment I'm testing your solution.
My question is: Did you something about OnUnload event?. I hope that yes. :). Bye

16 . Jesse Skinner on August 18th, 2006

Jesse Skinner

@Adam - I just tested using onreadystatechange on the actual document, and it doesn't seem to fire until the images have loaded, so it's the same effect as just using window.onload.

Anyway, I added your memory leak fix to the script. Thanks!

@James - I think you can just use the regular unload event, no special scripts required :)

17 . Jiri Vanmeerbeeck on September 20th, 2006

Jiri Vanmeerbeeck

It seems like VPC with IE still sees the function as a script, and thus blocks it. Can anything be done about this?

18 . Jiri Vanmeerbeeck on September 20th, 2006

Jiri Vanmeerbeeck

just because it was hosted locally, from the VPC desktop

19 . Khalid Anwar on October 11st, 2006

Khalid Anwar

Hi jessie,

Sorry I am a bit confused with this, or you may say I don't get it, as I used your web page without the adddomloadevent, but how I do it. By sticking javascript at the end of the HTML and I could not see any difference.

What I did was to comment out calling of functions
//addDOMLoadEvent(addFirstElement);

/*addDOMLoadEvent(function() {
addListElement("Thanks, addDOMLoadEvent!");
});*/

and then added a list item "Lets see when this will be displayed" within the ordered list in your html
and last I added
<script type="text/javascript">
addFirstElement(); alert('text displayed');
</script>
just before the body end tag in the html.

The resulting web page displays exactly as your does that is with all list items displayed before the picture finish downloading and displayed on the web page.

20 . Jesse Skinner on October 11st, 2006

Jesse Skinner

@Khalid - You're right, putting a script tag at the end of the body is another method of doing the same thing. addDOMLoadEvent offers a way of doing this in an external JS file without adding extra markup in the HTML.

Not only does this clean up your code, it makes it more portable. This way you have one less thing to remember about to add the script to another page (or remove it).

21 . Awflasher on October 30th, 2006

Awflasher

It helps me a lot wahoo~~

Thanks very much. There are many solutions, but your soluction is really light(<1kb) and easy!

a friend from China

22 . Mark Nottingham on November 2nd, 2006

Mark Nottingham

Hi! Thanks for wrapping this up; very nice.

Question - you use arguments.callee.done to determine whether init has been called yet. However, the actual events are stored in window.__load_events.

If two instances of the function are used by two different scripts in the same page, it seems like this would lead to the queue of events being run twice. Would it be better to use something like window.__events_done to determine whether it's been run? Or, to pop events off of the stack, to assure that they're not run more than once?

Thanks again,

23 . awflasher on January 28th, 2007

awflasher

Hi ... Some strange things ... Some times when I made some Js such as "document.write" in my DOM directly, the AddDomLoadEvent fires much earlier than it should be(It fires when the DOM is load only little)
Anyone meet with this problem and what may be the cause?
Thanks in advance.

24 . chaoskaizer on February 1st, 2007

chaoskaizer

it working perfectly on my site. gj tho

25 . Mark on February 19th, 2007

Mark

This script is really working perfectly, thanks for this. However I have come through an issue where I found that the onerror handler doesn't fire anymore.
Can you confirm that? Any help on that would be greatly appreciated

26 . Sören on March 30th, 2007

Sören

good work, Jesse!

nevertheless i have found a - let's say - strange behavior of ie (5-6) in a real world scenario. perhapes something like awflasher (post 23) is pointing out.
url: http://clients.silvr.net/_nortia/referenzen01.html

the odd thing is, that the script works like intended, but ie is like "choking" when loading the last images of the page. you can use the page and my additional scripts (something like a galerie), but ie "pretends" to be still loading images. appears only on the first page-view or if you refresh the page with F5.

i tried everything - delete all other script parts, test on a different webspace and another pc, even used another script (check for availability of the body-element in an interval - the old method) - but it's always the same.
before i used "onload" and it worked like a charme.

anybody any idea why this strange thing is happening?
i would really appreciate any(!) hint.

27 . Eduardo on April 8th, 2007

Eduardo

Hello,

I found your site because I was looking for a solution to replace my onload event. If you look at this site:

www.rodnelman.com/gallery.html

The transparency loads after everything else (thumbnails, text). I am JavaScript-ignorant and would like to know if I can apply your script to my page? Thanks

28 . Jesse Skinner on April 9th, 2007

Jesse Skinner

@Eduardo - Sure, I don't see why not. Just get rid of the

<body onload="transparentbg('bgopacity')">

and replace with addDOMLoadEvent like so:

addDOMLoadEvent(function(){
transparentbg('bgopacity');
});

29 . Eduardo on April 10th, 2007

Eduardo

Jesse: works like a charm!

Thanks a bunch!!!

30 . Nick on May 8th, 2007

Nick

Great script! - replacing "onload" has become a bit of a holy grail for me, and i've just finished testing addDomLoadEvent on a current development and it's working brilliantly in everything except IE5/Win. However, it's running as a standalone version (on XP/SP2), and I've no way of determining whether this is why it's throwing a tantrum :)

I know IE5's an antiquated piece of garbage but, assuming it it is down to the browser's long list of deficiencies, i was wondering if there's a way of either adding support for it, or some other means of hiding the addDOMLoad so the site simply runs unscripted (but without errors)?

31 . Jesse Skinner on May 8th, 2007

Jesse Skinner

@Nick - I suppose you could use conditional comments to hide the JavaScript from Internet Explorer < 6. Try this:

<![if gte IE 6]>
<script type="text/javascript" src="code.js"></script>
<![endif]>

Unfortunately this method uses invalid HTML. You could also just use another browser sniffer to detect IE < 6 and simply don't run the JavaScript.

32 . Nick on May 9th, 2007

Nick

Cheers Jesse, I'll give the sniffer a whirl. The script's running fine on IE5.5, and v5 wasn't even registering on the stats for the previous site.

Thanks again :)

33 . dd on May 17th, 2007

dd

This is great, but is there a non-IE equivalent of the following code: ?

if ( document.readyState == “complete” )

I have some cases where I try using the onload handler (IE) or the DOMContentLoaded event, only to discover (by the lack of anything happening) that the events must have already been thrown before I registered.

The situation is that I have an iframe which wants to dynamically add content into the parent page. For IE I can look at parent.document.readyState, but for non-IE there doesn’t seem to be a property. I had high hopes once I found Dean’s work, but it seems to not meet my requirements.

The iframe code has no idea whether or not the parent page has finished loading, so just signing up for an onload/DOMContentLoaded event is no good.

For example, here's the logic I could implement now for IE:

if ( parent.document.readyState == "complete")
deploy_elements_into_parent_page();
else
window.onload=deploy_elements_into_parent_page;

I couldn't achieve the same thing for non-IE.

Any ideas ?

34 . Jesse Skinner on May 17th, 2007

Jesse Skinner

@dd - I'm not sure about a cross-browser 'readyState' property..

Maybe you could achieve this by using the polling technique used by YUI and others. eg. use setInterval to periodically check (every 50ms or so) if the elements you need to access are on the page yet.

35 . dd on May 20th, 2007

dd

Thanks for the reply Jesse. Unfortunately there aren't any specific elements I can look for - I deploy into various different parent pages and can't rely on any specific element existing. Checking for document.body doesn't help either, that pretty much exists as soon as the <body> tag is parsed.

I'm running in an iframe in a closed document and want to deploy some DIV's and some SCRIPT elements into a parent page that may or may not be already closed also. If it's not closed, it may or may not have reached DOM scriptability point.

As I'm sure you're aware, trying to add elements to the DOM prior to the scriptability point can result in one of two conditions. In Win/IE you get that horrible "Internet operation aborted error". In Firefox you just get a silent failure when you're adding script. If you then try to access some of the variables in that script you get object does not exist. Perhaps the .appendChild call returned an error code, I haven't checked for that. I would have expected it to throw an exception though, return codes aren't generally used.

36 . Marcos Buarque on June 9th, 2007

Marcos Buarque

Hi, this script is great. Maybe you can point me out a solution for this: The same function I call when the page is loaded must be called everytime the user resizes its browser window. The problem is I can't use <body onresize="FunctionName">. So I want to add a listener that does this. Is there a script out there that allows me to do this? Thanks and sorry if the question is too stupid.

37 . Jesse Skinner on June 9th, 2007

Jesse Skinner

@Marcos - You have basically 2 options for dealing with resize. You can set window.onresize = function(){}, or you can use setInterval to check every 100ms or so if the window has resized.

If you use onresize(), be careful how much code you run during a resize, though. In Internet Explorer, the onresize() event is called for every pixel the browser size changes - and having some very complex calculations can cause the browser to hang!

38 . jindw on June 24th, 2007

jindw

for your code:
// for Safari
if (/WebKit/i.test(navigator.userAgent)) { // sniff
window.__load_timer = setInterval(function() {
if (/loaded|complete/.test(document.readyState)) {
init(); // call the onload handler
}
}, 10);
}

the globals variable is not needed.
// for Safari
if (/WebKit/i.test(navigator.userAgent)) { // sniff
var load_timer = setInterval(function() {
if (/loaded|complete/.test(document.readyState)) {
clearInterval(load_timer);
init(); // call the onload handler
}
}, 10);
}

39 . Mike on July 4th, 2007

Mike

Have you tested this with the lasted version of FireFox 1.8.1.4, it seems to be broken. I have tested it with IE6, and Nescape 8.1.3 - which is from FireFox 1.7.5 and it works beautifully, but in FireFox 1.8.1.4 it did not load the images at all. Any Ideas?

40 . Diego Perini on August 6th, 2007

Diego Perini

Jesse,
the window.onload event will fire before the deferred script when the page does not contain images or when page size is bigger than total image size. Somebody use this to overwrite methods before "onload".

I know these are edge cases for your script scope however adding an extra "onreadystatechange" event to fire when the state is "complete" will avoid this minor problem. Adam Schlag already suggested that in #14.

The alternative is to "document.write" the following line instead:

<script type=”text/javascript” src=”//:” defer=”defer” onreadystatechange=”if(this.readyState == ‘complete’) { init(); }”></script>

or better, to avoid using "document.write" have this in the HEAD section.

You should tweak a bit your code to make the "init()" function accessible from the above script context or it will not be found as it is now, something like "addDOMLoadEvent.init()" if you make the method public.

Your event still has something that others does not have, the capability of queue up several functions. Keep up with the good work.

41 . Ash on August 18th, 2007

Ash

For some strange reason, the init() function is triggered after all the images have been loaded in IE6 (WinXP SP2). Any clues?

42 . Ash on August 18th, 2007

Ash

In IE6, I have noticed that the init() function doesn't trigger after DOM load (and before images load), if the page has iframe (typical of Google Adsense ads for example). To workaround this, I've modified Jesse's original script:

:
:
var load_events = [],
load_timer,
done_flag = false,
script,
init = function () {
// kill the timer
clearTimeout(load_timer);
clearInterval(load_timer);
:
:
// for Mozilla/Opera9
if (document.addEventListener)
{
done_flag = true;
document.addEventListener("DOMContentLoaded", init, false);
}

// for Internet Explorer
/*@cc_on @*/
/*@if (@_win32)
document.write("<scr"+"ipt id=__ie_onload defer src=//0></scr"+"ipt>");
script = document.getElementById("__ie_onload");
script.onreadystatechange = function() {
if (this.readyState == "loaded")
load_timer = setTimeout(init, 500);
};
done_flag = true;
/*@end @*/

// for Safari
if (/KHTML|WebKit/i.test(navigator.userAgent)) { // sniff
load_timer = setInterval(function() {
if (/loaded|complete/.test(document.readyState))
{
done_flag = true;
init(); // call the onload handler
}
}, 10);
}

// for other browsers
if ( !done_flag )
window.onload = init;
:
:

The first problem (IE specific) is that if the page has an iframe then the readyState is set to "complete" only after the iframe contents are also loaded. So we check for the "loaded" readyState and delay the init by 500ms to make sure the DOM is loaded by then. Still a hack, but it works.

The second problem is that init may be triggered twice, once for the browser-specific init trigger and again for the "window.onload", so we workaround that with a flag (done-flag).

Your views and suggestions are most welcome!

43 . Corey Gilmore on September 21st, 2007

Corey Gilmore

I made one small change to this to allow specifying a scope and arguments:

exec.func.apply(exec.scope || window, exec.args || []);

And you'll add events like this:

addDOMLoadEvent({func:someOnloadFunction, args:['text',{obj:'args'}]});

addDOMLoadEvent({func:someOnloadFunctinn, scope:myObjScope, args:['text',{obj:'args'}]});

addDOMLoadEvent({func:someOnloadFunction, scope:myObjScope});

addDOMLoadEvent({func:someOnloadFunction});

44 . Jesse Skinner on September 21st, 2007

Jesse Skinner

@Corey - Nice addition. You can achieve the same thing with the original code by doing the following:

addDOMLoadEvent(function(){
myObjScope.someOnloadFunction('text', {obj:'args'});
});

45 . Tercüme bürosu on October 30th, 2007

Tercüme bürosu

it working perfectly on my site gj tho...

46 . vitto on November 5th, 2007

vitto

hi
i'm trying to make your code work form a new site i'm working on but i can't make it wotk in IE. Has anyone any idea why?

these are the page i'm working on

http://office.azero.it/aidp.it/associazione/lombardia/index.php

thanks vitto

47 . seengee on November 25th, 2007

seengee

I have had a problem where $(id) or document.getelementbyid throws an error in IE (6 and 7 tested) when called within a function that is fired by addDOMLoadEvent. There is no issue in Firefox, is this expected behaviour ? If so is there a workaround ?

48 . seengee on November 25th, 2007

seengee

should have mentioned above, error generated by IE is:

'null' is null or not an object

49 . Lon F. Binder on December 13rd, 2007

Lon F. Binder

Jesse - great work!

I was having the same problem as seengee. It seems that if you mix document.write and other DOM manipulation (e.g., appendChild) in IE, then it won't recognize subsequent document.write('<script id='x'...') if immediately checked using document.getElementById('x'). I've seen this repeatedly in other scripts.

Because both document.write and DOM manipulation are useful in differing ways, the way I worked around this as by making the call asynchronous.

I resolved the problem here by changing lines 60-64 of the latest version (as of Dec 13, 2007) to:

load_timer = setInterval(function() {
script = document.getElementById("__ie_onload");
if(script==null)return;
script.onreadystatechange = function() {
if (this.readyState == "complete")
init(); // call the onload handler
};
clearInterval(load_timer);
}, 10);

- Lon

50 . Christian J on January 7th, 2008

Christian J

Hi there im i quite experiense designer but when it comes to more complicated javascript im quite new but learning alot on my way

i use Ash fix

:
:
var load_events = [],
load_timer,
done_flag = false,
script,
init = function () {
// kill the timer
clearTimeout(load_timer);
clearInterval(load_timer);
:
:
// for Mozilla/Opera9
if (document.addEventListener)
{
done_flag = true;
document.addEventListener("DOMContentLoaded", init, false);
}

// for Internet Explorer
/*@cc_on @*/
/*@if (@_win32)
document.write("<scr"+"ipt id=__ie_onload defer src=//0></scr"+"ipt>");
script = document.getElementById("__ie_onload");
script.onreadystatechange = function() {
if (this.readyState == "loaded")
load_timer = setTimeout(init, 500);
};
done_flag = true;
/*@end @*/

// for Safari
if (/KHTML|WebKit/i.test(navigator.userAgent)) { // sniff
load_timer = setInterval(function() {
if (/loaded|complete/.test(document.readyState))
{
done_flag = true;
init(); // call the onload handler
}
}, 10);
}

// for other browsers
if ( !done_flag )
window.onload = init;
:
:

my question is how to get this fixed to work with the script

window.onload = initShowHideDivs;

window.onload = SymInitWinOnload();

51 . Jesse Skinner on January 7th, 2008

Jesse Skinner

@Christian - Maybe you want to do this?:

addDOMLoadEvent(initShowHideDivs);
addDOMLoadEvent(SymInitWinOnload);

52 . Christian J on January 7th, 2008

Christian J

wow that was fast thanks alot :) will give a link when me site is done think u will like it =D

cheers mate

53 . Christian J on January 7th, 2008

Christian J

okey i thought i got the hang of it but oblivusly not...

* To use: call addDOMLoadEvent one or more times with functions, ie:
*
* function something() {
* // do something
* }
* addDOMLoadEvent(something);
*
* addDOMLoadEvent(function() {
* // do other stuff
* });
*

could u be so kind to fix my
addDOMLoadEvent(initShowHideDivs);
addDOMLoadEvent(SymInitWinOnload);

to that would be greatful

54 . Jake on February 14th, 2008

Jake

Yo whats happenin jessie. Nice work on this code. I'll be using it with some of my flash development. Im creating a prototype for my company in which we'll have a video playing and a corresponding transcript in a different frame and have the ability to sync the current playheadtime of the video to the specific spot in the text transcript and then visa versa (syncing the text to the specific timestamp in the video). Its pretty killer, but for some reason some of my event listeners in actionscript dont work properly and that is how i ended up at your page. My question is, it looks like you updated the js file in August (19th) of 2007 but i cant find the file. Hopefully you are still using this blog and still have the file. Keep me posted and great work!

-Jake

55 . Jake on February 14th, 2008

Jake

Also in reference to my post above. Will this matter if we have frames within frames? I know frames, can yah believe it. HA! My company is huge which makes us a follower when it comes to technology so we're slowly getting to Web2.0 standards, but i have to make this work with frames for the old stuff as well.
Thanks again,
-Jake

56 . Tri Doan on March 10th, 2008

Tri Doan

It seems that this doesnt work too well after running through a jsmin operation...for IE only i've noticed. Jsmin strips out all comments, which is probably what's causing it to fail. I have yet to find a solution though, but just wanted to throw this out there incase someone else was having some similar issues.

57 . CRMZepher on April 3rd, 2008

CRMZepher

Hello All,

Great thread. I have an interesting problem with some great code developed by Scott Hemmeter at http://sfdc.arrowpointe.com for Salesforce CRM. He has made a realtime Sidebar Summary that using the OnLoad command queries the SF database and returns values for the number of leads, contacts, sales, etc . . that the user currently has in their name. It is programmed in Javascript and works in Salesforce via their S-Control and HTML IFrame Embedded options.

We have tested the the code for 3 days with rave results from our users for the content but with dispair on the page load time. Each time they click on a new page in the CRM system the code queries the DB thus slowing things down.

What I would like to do is make so that page loads faster or only loads new data once every 30 pages views, so it won´t slow down the user experience too much.

My thoughts . . .

1. Maybe we can use what you all have created here. I have no idea if that is possible given the nature of Salesforce and you can´t code to core html of the page but you can easily add any html to the Scontrols and HTML components that load on the page.

2. Rework the existing Onload to load to work only every 30 page views, or every 15 mins, etc . . . something to that effect to reduce its effect on the user.

The Salesforce Sidebar Summary can be seen at http://sfdc.arrowpointe.com/2007/08/28/sidebar-summary/ and Scott´s suggestion on this point at the bottom.

Anyone up to helping me improve this code? I can help provide access to Salesforce to test the code. I am decent JS, HTML, Java Web hack but not at the level that you all discussing. But I am always willing to learn and compensate my benefactors.

Here is the basics on the code . . .

******************BEGINNING ***************

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<script src="/soap/ajax/10.0/connection.js"></script>
<link href="/dCSS/Theme2/default/common.css" type="text/css" rel="stylesheet" >
<style type="text/css" media="all">
body{margin: 0; padding: 0; font-family: Arial, Verdana; color: #000000; background-color: #E8E8E8;}
table tr td {font-size: .6em;}
#DIV_HPS_Container {background-color: #F3F3EC;}
</style>
<script type="text/javascript">

/****************************************************************
* Called from the body onload event.
* This is the main function that calls getCount function for each entry you want
*****************************************************************/
function main() {

*
*
*
*
*
*

************ BOTTOM OF CODE********************

var valueHTML = qry.size;
if (url != "") {
valueHTML = '<a href="' + url + '" target=_parent title="View ' + label + '"><b>' + qry.size + '</b></a>';
}

retval += "<tr><td><em>" + label + "</em>:&nbsp;&nbsp;</td><td>" + valueHTML + "</td></tr>";
}

return retval;
}

</script>
</head>
<body onload="main()">
<div id="DIV_HPS_Container"></div>
</body>
</html>

************ END OF CODE ********************

Cheers!! Paul

58 . Hugo on May 22nd, 2008

Hugo

Hi there, this is exactly what I need for an open source project. But I can't use it since there's no license except a copyright here. It would be nice with an apache license? or a CC attribution license?

BR, Hugo

59 . Bidon on October 26th, 2008

Bidon

If you want inline onloads to work (e.g "<body onload="execute_me()">"), you will need to replace o() by (o.call&&o()||eval(o)) in the compressed version.
It execute a fonction if onloads holds a function, or evalute its code it it holds a string.
Thank you for this code! An alternative license would be great indeed ^^

60 . Pachepa on March 3rd, 2009

Pachepa

Awesome Script!!
Thank you.

61 . Niall on April 1st, 2009

Niall

This script causes a 502 bad gateway error in IE.
This is a direct consequence of the script tags that are written out in the cc section.

62 . Nico on May 24th, 2009

Nico

Hi,

I've quite the same problem than dd in comment 33. There is no equivalent to document.readyState for Firefox. I tested your script in Firefox after page has fully loaded - no execution of the function.

In my case it's not an iframe which checks the state of a parent document but a firefox extension which checks the document currently shown in the browser. So there is also no way to check the document for expected elements.

Any idea how to deal with that. I think an elegant solution for that problem would be helpful for lots of people.

Maybe there is a special window.document property which is different before and after loading a document completely. I also thought about comparing document.body.innerHTML in an timer interval - but how to make sure that the interval is always long enough.

Quite tricky I think - any ideas.

P.S.: Question marks in blog comments cause problems.

63 . thor on April 21st, 2010

thor

This script causes a 502 bad gateway error in IE.
This is a direct consequence of the script tags that are written out in the cc section.

yes an error in IE

Comments are closed, but I'd still love to hear your thoughts.