Change the execution order of $(document).ready()

If you use jQuery in development, you've almost definitely used $(document).ready(). $(document).ready() is a wonderful function that lets you run Javascript code as the page is ready to handle it. But one potentially frustrating aspect of it is that functions are executed in the same order they're passed in, and jQuery doesn't let you choose which functions run first.

Usually, this is fine, but every once in a while, you really want your function to run before another function. For example, if your page is running jCarousel or Google Maps, or any other library that changes the markup of your page, you might want to do some processing before they get a chance. With the traditional $(document).ready(), you'd be out of luck.

However, a quick look at the $(document).ready() internals shows a way to get what we want.

ready: function(fn) {
  // Attach the listeners
  bindReady();
 
  // If the DOM is already ready
  if ( jQuery.isReady )
    // Execute the function immediately
    fn.call( document, jQuery );
 
  // Otherwise, remember the function for later
  else
    // Add the function to the wait list
    jQuery.readyList.push( fn );
 
  return this;
},

It's not really important to understand everything that's going on here, so don't worry about the Javascript. First, the function tells the browser to alert jQuery when it's done loading. Next, it checks if the browser is already ready, to see if you're running a function long after the page has already loaded. If the page is ready, jQuery will just run the function immediately. But if the page hasn't finished loading (the usual case for $(document).ready() logic), your function gets put on the end of a jQuery.readyList array. This is what we're after.

Before the page is finished loading, all of the functions added through $(document).ready() are put on the jQuery.readyList variable. If you want to change the order in which these functions are executed, all you have to do is alter this array.

Here's what it would look like to put your function at the front of the line for execution:

// Adding a function to $(document).ready() the regular way
$(document).ready(function() {
  // processing happens here
});
 
// Adding a function to the front of the list
$.readyList.unshift(function() {
  // processing here
});

Of course, this shouldn't be overused. Other jQuery authors expect functions to run in the order they're added, so they might be thrown off if the readyList is modified too much. Still, a small change like this can save a lot of headache in the right situation.

Notes:
Array manipulation is a bit beyond the scope of this post, but w3schools has a good reference on that here: JavaScript Array Object - w3schools.com

This should work in jQuery 1.3.x and 1.2.x, but will not work in 1.4. The readyList variable in 1.4 is no longer attached to the jQuery object, so it's no longer accessible to outside code.

Comments

dalin (not verified)

The slightly hackier way that I've accomplished this is simply to not use $.document.ready(function(/* Do something */){});
and instead just directly performed my action.

The downside of this is that it will block the browser from rendering/downloading assets. But as long as your action is minor it shouldn't be too big a deal.

Recent Posts

6.29.2012
By: Matthew Krick | 0 Comments
6.27.2012
By: Evan Jenkins | 4 Comments
3.14.2012
By: Tom Friedhof | 1 Comment
2.28.2012
By: Tom Friedhof | 9 Comments

From this Author

5.20.2009
By: Kevin Herrington | 1 Comment
Twitter icon
Facebook icon
Flickr icon