views:

4619

answers:

5

I have a script that uses $(document).ready, but doesn't use anything else from jQuery. I'd like to lighten it up by removing the jquery dependency.

How can I implement that functionality without it? It does more than window.onload.

+26  A: 

It's much more complicated than just window.onload

jQuery Source:

function bindReady(){
    if ( readyBound ) return;
    readyBound = true;

    // Mozilla, Opera and webkit nightlies currently support this event
    if ( document.addEventListener ) {
     // Use the handy event callback
     document.addEventListener( "DOMContentLoaded", function(){
      document.removeEventListener( "DOMContentLoaded", arguments.callee, false );
      jQuery.ready();
     }, 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", function(){
      if ( document.readyState === "complete" ) {
       document.detachEvent( "onreadystatechange", arguments.callee );
       jQuery.ready();
      }
     });

     // If IE and not an iframe
     // continually check to see if the document is ready
     if ( document.documentElement.doScroll && window == window.top ) (function(){
      if ( jQuery.isReady ) return;

      try {
       // If IE is used, use the trick by Diego Perini
       // http://javascript.nwbox.com/IEContentLoaded/
       document.documentElement.doScroll("left");
      } catch( error ) {
       setTimeout( arguments.callee, 0 );
       return;
      }

      // and execute any waiting functions
      jQuery.ready();
     })();
    }

    // A fallback to window.onload, that will always work
    jQuery.event.add( window, "load", jQuery.ready );
}
Chad Grant
+2  A: 

the ready function in jQuery does a number of things. Frankly, I don't see that point of replacing it unless you have amazingly small output from your website. jquery is a pretty tiny library, and it handles all sorts of cross-browser things you'll need later.

Anyway, there's little point in posting it here, just open up jquery and look at the bindReady method.

It starts by calling either document.addEventListener("DOMContentLoaded") or document.attachEvent('onreadystatechange') depending on the event model, and goes on from there.

tnyfst
+2  A: 

The most basic version of this is the "load" event fired from the current window object.

It has many looks

<script type="text/javascript">
    window.onload = function() {
        // do stuff
    }
</script>

But since window is usually implicit, you can also just do this 99% of the time (exception: working w/framesets)

<script type="text/javascript">
    onload = function() {
        // do stuff
    }
</script>

You'll also see it done with the body's onload property

<script type="text/javascript">
    function initStuff() {
        // do stuff
    }
</script>

<body onload="initStuff()">

But all of these methods are destructive - if a previous function was attached to onload, each of these will destroy or override that previous function attachment. The best way is to write a simple abstractor and use it

<script type="text/javascript">

function addEvent( obj, evt, fn )
{
    if ( typeof obj.attachEvent != 'undefined' )
    {
     obj.attachEvent( "on" + evt, fn );
    }
    else if ( typeof obj.addEventListener != 'undefined' )
    {
     obj.addEventListener( evt, fn, false );
    } else {
     // Do you want to support browser this old? 
     // If so, you'll need to accomodate it here
    }
}

addEvent( window, 'load', function()
{
    // Initialization stuff here
} );

</script>
Peter Bailey
onLoad is not a simpler version of jQuery's document.ready; it's completely different.
J-P
Well yes, that's fine. That point has already been made in other answers. Still, if we are to approach this problem from removing the jQuery dependency, then this is a low-path-of-resistance solution.
Peter Bailey
+2  A: 

What about js code that is placed in a script tag at the bottom of the document, say after the closing body tag? Will that get executed at the correct time? (it seems to for me)

Admittedly this might not suit everyone's purposes since it requires changing the html file rather than just doing something in the js file a la document.ready, but still....

rob
It seems to me that there were compatibility issues, like, since the page is not yet ready, you can't do this or that in these and those browsers. Unfortunately I cannot remember more clearly. Nonetheless +1 for a way that is close enough in 99% of all cases (and suggested by Yahoo!).
Boldewyn
A: 

I was recently using this for a mobile site. This is John Resig's simplified version from "Pro JavaScript Techniques". It depends on addEvent.

var ready = ( function () {
  function ready( f ) {
    if( ready.done ) return f();

    if( ready.timer ) {
      ready.ready.push(f);
    } else {
      addEvent( window, "load" isDOMReady );
      ready.ready = [ f ];
      ready.timer = setInterval(isDOMReady, 13);
    }
  };

  function isDOMReady() {
    if( ready.done ) return false;

    if( document && document.getElementsByTagName && document.getElementById && document.body ) {
      clearInterval( ready.timer );
      ready.timer = null;
      for( var i = 0; i < ready.ready.length; i++ ) {
        ready.ready[i]();
      }
      ready.ready = null;
      ready.done = true;
    }
  }

  return ready;
})();
James