Javascript domready?

Edit: As the year 2018 comes upon us, I think it's safe to listen for the DOMContentLoaded event.

function fireOnReady() { /* ... */ }
if (document.readyState === 'complete') {
    fireOnReady();
} else {
    document.addEventListener("DOMContentLoaded", fireOnReady);
}

Please note, the event will only fire once when your page loads! If you have to support really old browsers, then check out the super lightweight script I put together below.



For historical reference only:



jQuery has an undocumented property called isReady which is used internally to determine whether the DOM ready event has fired:

if($.isReady) {
    // DOM is ready
} else {
    // DOM is not yet ready
}

I started at 1.5.2 went back as far as 1.3.2 and the property is there. While undocumented, I would say that you can rely on this property in future versions of jQuery. Edit: And a year later - v1.7.2, they still use $.isReady - still undocumented, so please use at your own risk. Be careful when upgrading.

Edit: v1.9, they still use $.isReady - still undocumented

Edit: v2.0, with all of it's "major" changes, still uses $.isReady - still undocumented

Edit: v3.x still uses $.isReady - still undocumented

Edit: As several people have pointed out, the above does not really answer the question. So I have just created a mini DOM ready snippet which was inspired by Dustin Diaz's even smaller DOM ready snippet. Dustin created a neat way to check the document readyState with something similar to this:

if( !/in/.test(document.readyState) ) {
    // document is ready
} else {
    // document is NOT ready
}

The reason this works is because the browser has 3 loading states: "loading", "interactive", and "complete" (older WebKit also used "loaded", but you don't have to worry about that any more). You will notice that both "loading" and "interactive" contain the text "in"... so if the string "in" is found inside of document.readyState, then we know we are not ready yet.


While I usually advocate avoiding using frameworks unless necessary, I'd say using one in this case is perfectly fine. Here's jQuery:

$(function () {
    // do stuff after DOM has loaded
});

Note that it is NOT the same as an window.onload event, since onload executes first after other resources have been loaded (images etc.) The code I used in my example will execute when the DOM has finished loading, i.e., when the full HTML structure is available (not necessarily when images, CSS, etc. is available.)

If you want a checkable variable, you can set one in the ready-function:

var documentIsReady = false;
$(function () { documentIsReady = true; });

Of course you can find even more light-weight libraries than jQuery if all you want to do is to check for DOM-ready. But use a library in cases where different browsers behave very differently (this is one such case.)

Using some code from the DOMAssistant library, making your own "DOM is ready" function shouldn't be too hard:

var domLoaded = function (callback) {
    /* Internet Explorer */
    /*@cc_on
    @if (@_win32 || @_win64)
        document.write('<script id="ieScriptLoad" defer src="//:"><\/script>');
        document.getElementById('ieScriptLoad').onreadystatechange = function() {
            if (this.readyState == 'complete') {
                callback();
            }
        };
    @end @*/
    /* Mozilla, Chrome, Opera */
    if (document.addEventListener) {
        document.addEventListener('DOMContentLoaded', callback, false);
    }
    /* Safari, iCab, Konqueror */
    if (/KHTML|WebKit|iCab/i.test(navigator.userAgent)) {
        var DOMLoadTimer = setInterval(function () {
            if (/loaded|complete/i.test(document.readyState)) {
                callback();
                clearInterval(DOMLoadTimer);
            }
        }, 10);
    }
    /* Other web browsers */
    window.onload = callback;
};

Not tested, but it should work. I simplified it from DOMAssistant, because DOMAssistant allows multiple callbacks and has checking to make sure you can't add the same function twice etc.