• addDOMLoadEvent

    Jun 21 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 at 8:25am on June 22, 2006

    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 at 8:32am on June 22, 2006

    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 at 8:36am on June 22, 2006

    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 at 8:55am on June 22, 2006

    @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 at 12:22pm on June 22, 2006

    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 at 8:52am on June 26, 2006

    @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 at 8:56am on June 26, 2006

    @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 at 1:07am on June 28, 2006

    @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 at 7:37am on June 30, 2006

    @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 at 8:15am on June 30, 2006

    @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 at 11:14am on July 3, 2006

    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 at 12:47am on July 7, 2006

    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 at 5:51pm on August 9, 2006

    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 at 11:01am on August 16, 2006

    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 at 7:10pm on August 16, 2006

    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 at 3:14am on August 18, 2006

    @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 at 11:52am on September 20, 2006

    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 at 12:04pm on September 20, 2006

    just because it was hosted locally, from the VPC desktop

    19. Khalid Anwar at 3:43am on October 11, 2006

    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 at 11:02am on October 11, 2006

    @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 at 11:41pm on October 30, 2006

    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 at 12:04am on November 2, 2006

    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 at 11:46pm on January 28, 2007

    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 at 5:02pm on February 1, 2007

    it working perfectly on my site. gj tho

    25. Mark at 11:02am on February 19, 2007

    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 at 7:57am on March 30, 2007

    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 at 6:48pm on April 8, 2007

    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 at 3:41am on April 9, 2007

    @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 at 2:06am on April 10, 2007

    Jesse: works like a charm!

    Thanks a bunch!!!

    30. Nick at 8:42am on May 8, 2007

    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 at 8:56am on May 8, 2007

    @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 at 10:22am on May 9, 2007

    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 at 6:42pm on May 17, 2007

    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 at 6:47pm on May 17, 2007

    @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 at 7:17am on May 20, 2007

    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 at 1:05am on June 9, 2007

    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 at 5:27am on June 9, 2007

    @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 at 12:05am on June 24, 2007

    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 at 9:47am on July 4, 2007

    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 at 7:22pm on August 6, 2007

    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 at 2:53am on August 18, 2007

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

    42. Ash at 6:16am on August 18, 2007

    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 at 10:39am on September 21, 2007

    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 at 12:22pm on September 21, 2007

    @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 at 10:50am on October 30, 2007

    it working perfectly on my site gj tho...

    46. vitto at 9:17am on November 5, 2007

    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 at 8:42am on November 25, 2007

    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 at 8:50am on November 25, 2007

    should have mentioned above, error generated by IE is:

    'null' is null or not an object

    49. Lon F. Binder at 5:00pm on December 13, 2007

    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 at 6:33pm on January 7, 2008

    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 at 6:35pm on January 7, 2008

    @Christian - Maybe you want to do this?:

    addDOMLoadEvent(initShowHideDivs);
    addDOMLoadEvent(SymInitWinOnload);

    52. Christian J at 6:37pm on January 7, 2008

    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 at 6:50pm on January 7, 2008

    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 at 11:30am on February 14, 2008

    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 at 11:38am on February 14, 2008

    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 at 6:59pm on March 10, 2008

    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 at 1:38pm on April 3, 2008

    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 at 5:27pm on May 22, 2008

    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 at 3:16am on October 26, 2008

    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 at 7:15pm on March 3, 2009

    Awesome Script!!
    Thank you.

    61. Niall at 5:23am on April 1, 2009

    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 at 5:34pm on May 24, 2009

    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 at 6:05am on April 21, 2010

    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

    Commenting is now closed. Come find me on Twitter.