We've talked a good bit about selectors. A jQuery selector like $("h1") will select all <h1> elements on the page. But what about... when it doesn't? Here's an example of when that selector would fail:

<!doctype html>
<html lang="en">

<head>
  <meta charset="UTF-8">

  <title>Learning jQuery</title>

  <script src="js/jquery-2.0.3.js"></script>
  <script>
    $("h1").css("color", "red");
  </script>
</head>

<body>
  
  <h1>Hello, World!</h1>

</body>

</html>

Will that <h1> element be red? Nope. WTF right? The reason it doesn't turn red is because when that jQuery code runs, there is no <h1> for it to find yet. It hasn't yet made it to the DOM. That is because your HTML is read from top to bottom. Imagine the browser reading the very first line, then the next, then the next. When it gets down to the line with the jQuery selector on it, it only knows about that line and all above it. So no <h1> is found and no color changing happens.

How do we deal with this problem? The best way to handle this is to load JavaScript files at the bottom of your page. Right above the closing </body> tag. JavaScript files "block" page rendering as they are downloaded and ran, so it will make your page load faster anyway. But that means that our jQuery selectors will find everything they are supposed to find as a bonus.

Loading the scripts at the bottom would look like this:

<!doctype html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Learning jQuery</title>
</head>

<body>
  
  <h1>Hello, World!</h1>

  <script src="js/jquery-2.0.3.js"></script>
  <script>
    $("h1").css("color", "red");
  </script>

</body>

</html>

But sometimes scripts are loaded in the head. There are all kinds of excuses for it, mostly bad, but hey let's not get too judge-y without details =).

We can still fix the not-finding-elements issue in a pretty satisfactory way even if we are forced to load scripts in the head. We do it through the jQuery "DOM Ready" function. Literally, when the document is done and ready to be manipulated. It looks like this:

$(document).ready(function() {

});

There is a shorter version which does the exact same thing:

$(function() {

});

Putting your code inside a function like that ensures it won't run until the document is ready. It's actually a rather clever bit of code that does it, which of course is difficult to do cross-browser. What is cool about it is that it is pretty fast. It's not the same as waiting for the entire window to load, which is slow, because it waits for all resources to be done downloading before firing. DOM ready happens much sooner. If you do need to wait for resources to be done (e.g. you need to measure an image), you can wait for that like this:

$(window).load(function() {

});

Fixing our earlier JavaScript-in-the-head problem with DOM ready, the code would look like this:

<!doctype html>
<html lang="en">

<head>
  <meta charset="UTF-8">

  <title>Learning jQuery</title>

  <script src="js/jquery-2.0.3.js"></script>
  <script>
  $(function() {
    $("h1").css("color", "red");
  });
  </script>
</head>

<body>
  
  <h1>Hello, World!</h1>

</body>

</html>

Comments

  1. User Avatar
    Ron Gilmour
    Permalink to comment#

    Huh. I had this idea that jQuery had to have a “document ready” wrapper, but I guess that’s only if your code is in the head. Thanks for clarifying that. I’m going to go clean up some code now.

  2. User Avatar
    Richard Finelli
    Permalink to comment#

    Yes, I was under the same impression as Ron. And now I understand what the shorthand code is for dom ready which clarifies a bunch.

  3. User Avatar
    ricardo garcia
    Permalink to comment#

    I didn’t know there was a shorthand code for this. I’ve never seen that in any turial which means this is getting better and better. Thanks Chris I love your Methodology :)

  4. User Avatar
    Greg
    Permalink to comment#

    Hi, thanks for this explanation. Makes things clear. Can you confirm that the following code samples are equivalent?

    $(document).ready(function(){
        //example
        $('h1').css("color", "blue");
    });
    

    same as

    jQuery(document).ready(function($){
        //example
        $('h1').css("color", "blue");
    });
    

    same as

    $(function() {
        //example
        $('h1').css("color", "blue");
    });
    

    same as

    jQuery(function($) {
        //example
        $('h1').css("color", "blue");
    
    });
    

    I think I like jQuery(function($)> best because I don’t have to include a noConflict.js file in the document.

    • User Avatar
      Chris Coyier
      Permalink to comment#

      Those will indeed all function the same. And yes the last one (same as the second one) will allow you to safely use the $ inside without conflict. You don’t always need a DOM ready statement though (like all four of those are), for example if you correctly load scripts at the bottom of the page (the DOM will already be ready). So this is a pattern with the same safetey without the DOM Ready:

      (function($){  
        // use $ here safely
      })(jQuery);
      
  5. User Avatar
    Rachel
    Permalink to comment#

    great video :) like when you are like we could do this too or whatever… lol

Submit a Comment

Posting Code

You may write comments in Markdown. This makes code easy to post, as you can write inline code like `<div>this</div>` or multiline blocks of code in triple backtick fences (```) with double new lines before and after.

Code of Conduct

Absolutely anyone is welcome to submit a comment here. But not all comments will be posted. Think of it like writing a letter to the editor. All submitted comments will be read, but not all published. Published comments will be on-topic, helpful, and further the discussion or debate.

Want to tell us something privately?

Feel free to use our contact form. That's a great place to let us know about typos or anything off-topic.

icon-anchoricon-closeicon-emailicon-linkicon-logo-staricon-menuicon-nav-guideicon-searchicon-staricon-tag