TLDR;
If you place your JS/jQuery below the elements, you don’t have to use $(document).ready.
Wrapping all your Javascript in a $(document).ready. All the cool kids are doing it, and it is safe to do so. However, this doesn’t come without drawbacks. Also, there multiple considerations when it comes to loading jQuery itself, but that’s a different conversation.
jQuery SHOULD be loaded on the footer of your <html>. At this point, wrapping or not doesn’t really matter. The magic lies in the fact the by the time your JS runs, the elements are already on the page (aka above the script you are running ).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<html> <head> <title>To .ready or not to .ready</title> </head> <body> <p id="first">Some random text here</p> <p id="second">Some random text here 2</p> <p id="third">Some random text here 3</p> <div> Some div content </div> <script src="http://code.jquery.com/jquery-1.12.0.min.js"></script> <script> // No need to wrap, but go ahead, it can't hurt. $( document ).ready( function() { $( '#first' ).css( 'background', 'yellow' ); $( '#second' ).css( 'background', 'blue' ); $( '#third' ).css( 'background', 'red' ); } ); </script> </body> </html> |
But let’s say you are forced to load jQuery in the <head> AND you are also forced (or want) to place your JS on <head> as well … now you HAVE to use $(document).ready( function() {} ); because by the time the JS runs, the elements to be selected haven’t been seen by the browser yet.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<html> <head> <title>To .ready or not to .ready</title> <script src="http://code.jquery.com/jquery-1.12.0.min.js"></script> <script> // You have to wrap, or nothing will happen $( document ).ready( function() { $( '#first' ).css( 'background', 'yellow' ); $( '#second' ).css( 'background', 'blue' ); $( '#third' ).css( 'background', 'red' ); } ); </script> </head> <body> <p id="first">Some random text here</p> <p id="second">Some random text here 2</p> <p id="third">Some random text here 3</p> <div> Some div content </div> </body> </html> |
From https://learn.jquery.com/using-jquery-core/document-ready/
Code included inside
$( document ).ready()
will only run once the page Document Object Model (DOM) is ready for JavaScript code to execute. Code included inside$( window ).load(function() { ... })
will run once the entire page (images or iframes), not just the DOM, is ready.
Here’s where the issue lies. When you use $(document).ready() you need to wait for the entire page to load! So, if you want to have your JS do some kind of effect, like a sticky sidebar, or transitions, or anything at all, they will not happen instantly. Sometimes, this isn’t an issue, but the more images and external script your page has, the longer it takes for your js to run. This can be unacceptable, as most of the times, this causes your effect to start working at weird times, making the site … well … act weird.
The solution: instead of wrapping in .ready(), place the <script> just below the elements you want it to work on. Again, by the time your script runs, the elements have already been “seen” by the browser, and the effects will kick in even though the page hasn’t completely loaded yet. No need to wait.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<html> <head> <script src="http://code.jquery.com/jquery-1.12.0.min.js"></script> </head> <body> <p id="first">Some random text here</p> <p id="second">Some random text here 2</p> <p id="third">Some random text here 3</p> <script> // Wait? Ain't nobody got time for that $( '#first' ).css( 'background', 'yellow' ); $( '#second' ).css( 'background', 'blue' ); $( '#third' ).css( 'background', 'red' ); </script> <div> Some div content </div> </body> </html> |