Cross-browser wrapper for DOMContentLoaded event. Start manipulating the DOM with Javascript as soon as the document is ready.

/*!
 * contentloaded.js, v20101020
 * Cross-browser wrapper for DOMContent loaded
 *
 * @link http://javascript.nwbox.com/ContentLoaded/
 * @link https://github.com/dperini/ContentLoaded
 *
 * @author Diego Perini <diego.perini@gmail.com>
 * @license: MIT, http://javascript.nwbox.com/ContentLoaded/MIT-LICENSE
 *
 * @param  {Object}   win Window reference
 * @param  {Function} fn  function reference
 */
function contentLoaded(win, fn) {
    var done = false,
        top = true,

        doc = win.document,
        root = doc.documentElement,

        add = doc.addEventListener ? 'addEventListener' : 'attachEvent',
        rem = doc.addEventListener ? 'removeEventListener' : 'detachEvent',
        pre = doc.addEventListener ? '' : 'on',

        init = function (e) {
            if (e.type == 'readystatechange' && doc.readyState != 'complete') return;
            (e.type == 'load' ? win : doc)[rem](pre + e.type, init, false);
            if (!done && (done = true)) fn.call(win, e.type || e);
        },

        poll = function () {
            try {
                root.doScroll('left');
            } catch (e) {
                setTimeout(poll, 50);
                return;
            }
            init('poll');
        };

    if (doc.readyState == 'complete') fn.call(win, 'lazy');
    else {
        if (doc.createEventObject && root.doScroll) {
            try {
                top = !win.frameElement;
            } catch (e) {}
            if (top) poll();
        }
        doc[add](pre + 'DOMContentLoaded', init, false);
        doc[add](pre + 'readystatechange', init, false);
        win[add](pre + 'load', init, false);
    }
}

//
// Usage
//

contentLoaded(win, function () {
    console.log('content loaded.');
});