$ is a function
When jQuery loads, it creates one global function called jQuery, and stores the same function in a shorter variable called $. These two lines are identical:
jQuery("p").hide();
$("p").hide();There is nothing magic about the dollar sign: it is a legal character in JavaScript names, and jQuery picked it because it is short. Almost every jQuery script uses $. (A later lesson covers WordPress, which deliberately frees $ and makes you use jQuery.)
Four things you can pass to $()
What $() does depends on what you give it:
<ul id="list"><li>One</li><li>Two</li></ul>
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
// 1. A CSS selector: find matching elements
const items = $("#list li");
console.log("selector found", items.length);
// 2. An HTML string: create new elements
const item = $("<li>Three</li>");
$("#list").append(item);
console.log("list now has", $("#list li").length);
// 3. A DOM element: wrap it so jQuery methods work on it
const plain = document.getElementById("list");
console.log("wrapped", $(plain).children().length);
// 4. A function: run it when the document is ready
$(function () {
console.log("document ready");
});
</script>selector found 2
list now has 3
wrapped 3
document readyThe first three forms return a jQuery object: a list-like wrapper around zero or more elements, with all of jQuery's methods attached. The fourth form schedules your function for later. You will use the first form most of the time.
The empty selection
If a selector matches nothing, jQuery does not throw an error. You get an empty jQuery object, and methods called on it do nothing:
<p>Only a paragraph here.</p>
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
const missing = $("#does-not-exist");
missing.hide(); // no error, nothing happens
console.log("length:", missing.length);
console.log("truthy?", Boolean(missing));
if (missing.length) {
console.log("found it");
} else {
console.log("nothing matched");
}
</script>length: 0
truthy? true
nothing matchedThis is convenient, but it can hide mistakes: a typo in a selector fails silently. When something "does nothing", check .length first. Note that a jQuery object is always truthy, even when it is empty, so if ($("#x")) is always true. Test .length instead.
Why you need document ready
The browser builds the page from top to bottom. A script runs as soon as the browser reaches it, so code in the <head> runs before the body exists. In this example the first script runs too early:
<head>
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
console.log("early:", $("#title").length);
$(function () {
console.log("ready:", $("#title").length);
$("#title").text("Found and changed");
});
</script>
</head>
<body>
<h1 id="title">Original title</h1>
</body>early: 0
ready: 1The early line finds nothing because #title has not been parsed yet. The code inside $(function () { ... }) waits until the whole document is parsed (the browser's DOMContentLoaded moment), so it finds the heading.
Three ways to write it
You will meet all of these in real code. They do the same thing:
$(function () {
// your code
});
$(document).ready(function () {
// your code (older, longer style)
});
jQuery(function ($) {
// your code; $ is passed in as a parameter
});The first is the recommended short form. The third is useful when $ might belong to another library: jQuery passes itself in as the first argument, so inside the function $ is safe to use.
Ready versus load
Document ready fires when the HTML is parsed. Images, fonts and iframes may still be downloading. If you need everything loaded, for example to measure the real size of an image, wait for the window's load event:
$(window).on("load", function () {
console.log("all images and styles have loaded");
});Most code only needs ready, which happens earlier, so the page feels faster.
Do I still need it with scripts at the bottom?
If your scripts are just before </body>, the elements above them already exist, so code works without document ready. Many developers still wrap their code in $(function () { ... }) because it also keeps their variables out of the global scope, and the code keeps working if someone moves the script tag to the head. In this course, short examples at the bottom of the body skip it for clarity.
Common mistakes
- Running code in the head without document ready, then wondering why nothing happens.
- Testing
if ($(selector))instead of.length. - Writing
$(document).readywith no function, such as$(document).ready(init()). That callsinitimmediately; pass the function itself:$(document).ready(init). - Waiting for
loadwhen ready is enough, which delays your page until every image arrives.
Exercise
Put jQuery and your script in the <head>. Inside document ready, log how many li elements are on the page, then add a new item that says Added when ready.
Show one possible answer
<head>
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
$(function () {
console.log($("li").length);
$("ul").append("<li>Added when ready</li>");
});
</script>
</head>
<body>
<ul><li>One</li><li>Two</li></ul>
</body>Key points
- $ is a short name for the jQuery function; $("p") and jQuery("p") do the same thing.
- $() takes a selector, an HTML string, a DOM element or a function, and returns a jQuery object (except for the function form).
- $(function () { ... }) runs your code once the HTML has been parsed, so elements exist when you select them.
- Selecting an element that does not exist yet gives an empty jQuery object, not an error, so nothing happens silently.