javascript:how to write $(document).ready like event without jquery

This is the way jQuery wraps the functions you're looking for - the snippet does not need jQuery, and is cross-browser compatible. I've replaced all calls to jQuery.ready() with yourcallback - which you need to define.

What goes on in here:

  • first, the function DOMContentLoaded is defined, which will be used when the DOMContentLoaded event fires - it ensures that the callback is only called once.
  • a check if the document is already loaded - if yes, fire the callback right away
  • otherwise sniff for features (document.addEventListener / document.attachEvent) and bind the callbacks to it (different for IE and normal browsers, plus the onload callback)

Lifted from jQuery 1.4.3, functions bindReady() and DOMContentLoaded:

/*
* Copyright 2010, John Resig
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*/
// Cleanup functions for the document ready method
// attached in the bindReady handler
if ( document.addEventListener ) {
DOMContentLoaded = function() {
    document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
    //jQuery.ready();
            yourcallback();
};

} else if ( document.attachEvent ) {
DOMContentLoaded = function() {
    // Make sure body exists, at least, in case IE gets a little overzealous 
            if ( document.readyState === "complete" ) {
        document.detachEvent( "onreadystatechange", DOMContentLoaded );
        //jQuery.ready();
                    yourcallback();
    }
    };
}

// Catch cases where $(document).ready() is called after the
// browser event has already occurred.
if ( document.readyState === "complete" ) {
    // Handle it asynchronously to allow scripts the opportunity to delay ready
//return setTimeout( jQuery.ready, 1 );
    // ^^ you may want to call *your* function here, similarly for the other calls to jQuery.ready
    setTimeout( yourcallback, 1 );
}

// Mozilla, Opera and webkit nightlies currently support this event
if ( document.addEventListener ) {
    // Use the handy event callback
document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
// A fallback to window.onload, that will always work
//window.addEventListener( "load", jQuery.ready, false );
    window.addEventListener( "load", yourcallback, false );
 // If IE event model is used
 } else if ( document.attachEvent ) {
        // ensure firing before onload,
        // maybe late but safe also for iframes
        document.attachEvent("onreadystatechange", DOMContentLoaded);

        // A fallback to window.onload, that will always work
        window.attachEvent( "onload", yourcallback );

 }

That's 51 lines of pure JavaScript code, just to register the event reliably. As far as I know, there is no easier method. Goes to show what the wrappers like jQuery are good for: they wrap the capability sniffing and ugly compatibility issues so that you can focus on something else.


Smallest DOMReady code, ever.

<html>
  <head>
    <script>
      var ready = function (f) {
        (/complete|loaded|interactive/.test(document.readyState)) ?
            f() :
            setTimeout(ready, 9, f);
      };
    </script>
  </head>
  <body>
    <script>
      ready(function () {
        alert('DOM Ready!');
      });
    </script>
  </body>
</html>

This is all you need if you're supporting IE9+ and modern (2013) versions of Chrome, FF, Safari, etc.

function ready(event) {
    // your code here
    console.log('The DOM is ready.', event);
    // clean up event binding
    window.removeEventListener('DOMContentLoaded', ready);
}

// bind to the load event
window.addEventListener('DOMContentLoaded', ready);