Chapter 4. Introducing jQuery
The first chapters of this book covered many of the fundamentals of the JavaScript programming language—the keywords, concepts, and syntax of JavaScript. Many of these concepts were fairly straightforward (“a variable is like a box in which you put a value”), but some topics may have had you scratching your head or reaching for a bottle of aspirin (like the “for” loops discussed on For Loops). The truth is, for most people, JavaScript programming is difficult. In fact, a 1,000-page book on JavaScript programming won’t cover everything there is to know about JavaScript and how it works in the many different web browsers out in the wild.
Programming is hard: That’s why this book covers both JavaScript and jQuery. As you’ll see in the first section of this chapter, jQuery is a JavaScript library that lets you jump-start your programming by handling many of the messy details of JavaScript programming for you. jQuery—whose motto is “write less, do more”—makes programming fun, fast, and rewarding. With jQuery, you can achieve in a single line of code what could take 100 lines of pure JavaScript programming. After you go through this and the following chapter, you’ll be able to achieve more with your web pages than if you studied that 1,000-page book on JavaScript alone.
About JavaScript Libraries
Many JavaScript programs have to deal with the same set of web page tasks again and again: selecting an element, adding new content, hiding and showing content, modifying a tag’s attributes, determining the value of form fields, and making programs react to different user interactions. The details of these basic actions can be quite complicated—especially if you want the program to work in all major browsers. Fortunately, JavaScript libraries offer a way to leap-frog past many time-consuming programming details.
A JavaScript library is a collection of JavaScript code that provides simple solutions to many of the mundane, day-to-day details of JavaScript. Think of it as a collection of prewritten JavaScript functions that you add to your web page. These functions make it easy to complete common tasks. In many cases, you can replace many lines of your own JavaScript programming (and the hours required to test them) with a single function from a JavaScript library. There are lots of JavaScript libraries out there, and many of them help create major websites like Yahoo, Amazon, CNN, Apple, and Twitter.
This book uses the popular jQuery library (www.jquery.com). There are other JavaScript libraries (see the box on the opposite page), but jQuery has many advantages:
Relatively small file size. A compressed version of the library is only around 90 k. (If your web server uses “gzip” compression, you can bring the file size down to just 30 k!)
Friendly to web designers. jQuery doesn’t assume you’re a computer scientist. It takes advantage of CSS knowledge that most web designers already have.
It’s tried and true. jQuery is used on millions of sites, including many popular, highly-trafficked websites like Digg, Dell, the Onion, and NBC. Even Google uses it in some places, and it’s built into the number one blogging software, WordPress. The fact that jQuery is so popular is a testament to how good it is.
It’s free. Hey, you can’t beat that!
Large developer community. As you read this, scores of people are working on the jQuery project—writing code, fixing bugs, adding new features, and updating the website with documentation and tutorials. A JavaScript library created by a single programmer (or one supplied by a single author) can easily disappear if the programmer (or author) grows tired of the project. jQuery, on the other hand, should be around for a long time, supported by the efforts of programmers around the world. Even big companies like Microsoft and Adobe are pitching in and supplying engineers and programming code. It’s like having a bunch of JavaScript programmers working for you for free.
Plug-ins, plug-ins, plug-ins. jQuery lets other programmers create plug-ins—add-on JavaScript programs that work in conjunction with jQuery to make certain tasks, effects, or features incredibly easy to add to a web page. In this book, you’ll learn about plug-ins that make validating forms, adding drop-down navigation menus, and building interactive slideshows a half-hour’s worth of work, instead of a two-week project. There are literally thousands of other plug-ins available for jQuery.
You’ve actually used jQuery in this book already. In the tutorial for Chapter 1 (Attaching an External JavaScript File), you added just a few lines of JavaScript code to create a page fade-in effect.
Getting jQuery
jQuery is simply a bunch of JavaScript programming in an external JavaScript file. Like any external JavaScript file (External JavaScript Files), you need to link it to your web page. However, because jQuery is so popular, you have a few choices when it comes to adding it to a web page: You can either use a version hosted at Google, Microsoft, or jQuery.com, or you can download the jQuery file to your own computer and add it to your website.
The first method uses a CDN or content distribution network—that is, another website hosts the jQuery file and sends it out to anyone who requests it. There are a couple of benefits to this approach: First, you can save your web server a few milliseconds by letting Google, Microsoft, or jQuery handle distributing the file to your site’s visitors. In addition, CDNs have the added benefit of having servers located around the globe. So if someone in Singapore, for example, visits your site, he’ll receive the jQuery file from a server that’s probably a lot closer to him than your web server, which means he’ll get the file faster and your site will appear to run more quickly. Lastly, and most importantly, because other designers use these CDNs as well, there’s a pretty good chance that someone visiting your site already has the jQuery file saved in their browser’s cache. Since he’s already downloaded the jQuery file from Google while visiting another site, he doesn’t need to download it again when visiting your site, resulting in a substantial speed increase.
There are a couple of downsides to using a CDN: First, visitors need to be connected to the Internet for this method to work. That becomes an issue if you need to make sure your site works offline, for example, in a kiosk at a museum or during a programming demonstration in a classroom. In that case, you need to download the jQuery file from jQuery.com (you’ll learn how below) and add it to your website. Adding your own jQuery file also ensures that your website will continue to work if the CDN servers go down. (Of course, if Google’s servers ever go down, then there may be bigger problems in the world than whether your website works.)
Linking to the jQuery file on a CDN server
Linking to the jQuery file on a CDN server
Microsoft, jQuery, and Google all let you include the jQuery file on one of your web pages using their servers. For example, to link to version 1.7.2 of jQuery using Microsoft’s CDN, you would add this line of code in the <head> of your web page (just before the closing </head> tag), like this:
<script
src=
"http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.2.min.js"
>
</script>
Using the jQuery CDN, you’d use this code:
<script
src=
"http://code.jquery.com/jquery-1.7.2.min.js"
></script>
And the code using Google’s CDN looks like this:
<script
src=
"
http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.
js
"></script>
You only need to use one of these lines on your page, based on the CDN you prefer to use. The Google CDN seems to be the most popular, so if you’re unsure of which to use, use the Google servers.
Downloading your own jQuery file
You can easily download the jQuery file and add it to your site along with all your other web pages and files. The tutorial files you downloaded for this book at www.sawmac.com/js2e/ include the jQuery library file, but since the jQuery team updates the library on a regular basis, you can find the latest version at http://docs.jquery.com/Downloading_jQuery, listed under the Current Release headline.
To download the latest version of jQuery:
Visit http://docs.jquery.com/Downloading_jQuery.
This page has information about the code, a list of the CDNs mentioned above, and previous versions of jQuery. You’re looking for the “Current Release.”
Click the “Current Release” link near the top of the page, or scroll down until you see the Current Release headline.
The jQuery file comes in two versions on the download site—minified and uncompressed. The uncompressed file is very large (over 200 k), and is only provided so you can learn more about jQuery by looking at its code. The code includes lots of comments (Comments) that help make clear what the different parts of the file do. (But in order to understand the comments, you need to know a lot about JavaScript.)
You should use the minified version for your websites. A minified file is much smaller than a regular JavaScript file: All JavaScript comments and unnecessary spaces are removed (tabs, linebreaks, and so on), making the file hard-to-read, but faster to download.
Right-click (Control-click on Mac) the Minified link and from the contextual menu that appears, choose Save Link As.
If you just click the link, you won’t download the file: Instead, the web browser displays all the code in a browser window; so you need to use this “Save as” method.
Navigate to the folder on your computer where you keep your website and save the file.
You can save the jQuery file anywhere you want on your site, but many web designers keep their external JavaScript files in a folder that’s dedicated to the purpose. Usually the folder has a name like scripts, libs, js, or _js.
Adding jQuery to a Page
If you’re using one of the CDN versions of jQuery (Linking to the jQuery file on a CDN server), you can point to it using one of the code snippets listed on Linking to the jQuery file on a CDN server. For example, to use the Google CDN version of jQuery, you’d add <script> tags to the head of the page like this:
<script
src=
"http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.
js"
></script>
Tip
When using the Google CDN, you can leave off parts of the version number. If you use 1.6 instead of 1.6.1 in the link (<script src=“http://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js”></script>), then Google loads the latest version in the 1.6 family—1.7.2, for example. If jQuery is updated to 1.6.9, then Google loads that version. This technique is smart since (as mentioned in the box on jQuery Versions) the minor version changes 1.6.1 to 1.6.9 are often bug fixes that will improve the functioning of your site.
Once you’ve downloaded jQuery to your computer, you must attach it to the web page you wish to use it on. The jQuery file is simply an external .js file, so you attach it just like any external JavaScript file, as described on External JavaScript Files. For example, say you’ve stored the jquery.js file in a folder named js in your site’s root folder. To attach the file to your home page, you’d add the following script tag to the head of the page:
<script
src=
"js/jquery-1.7.2.min.js"
></script>
Once you’ve attached the jQuery file, you’re ready to add your own scripts that take advantage of jQuery’s advanced functions. The next step is to add a second set of <script> tags with a little bit of jQuery programming in it:
<script
src=
"js/jquery-1.7.2.min.js"
></script>
<script>
$
(
document
).
ready
(
function
()
{
// your programming goes here
});
</script>
The second set of <script> tags holds any programming you want to add to the particular web page; however, you’re probably wondering what that $(document).ready() business is all about. The $(document).ready() function is a built-in jQuery function that waits until the HTML for a page loads before it runs your script.
Why would you want to do that? Because a lot of JavaScript programming is about manipulating the contents of a web page: for example, animating a div, fading an image into view, making a menu drop down when a visitor moves over a link, and so on. To do something fun and interactive with a page element, JavaScript needs to select it. However, JavaScript can’t select an HTML tag until the web browser downloads it. Since a web browser immediately runs any JavaScript it encounters, the rest of the page doesn’t download immediately. (You can see this effect in the quiz tutorial from the last chapter. When you load that quiz, the page is blank. Only after you finish the quiz does the content appear—that’s because the JavaScript for the quiz runs first, before the web browser displays the HTML tags.)
In other words, in order to do cool stuff to the HTML on your page, you need to wait until the page loads. That’s what the $(document).ready() function does: It simply waits until the HTML is finished loading and then it runs the JavaScript code. If all that seems super confusing, just keep in mind that you should always include a .ready() function and that you need to put your code inside it between $(document).ready(function() { and the final });.
In addition, here are a few things to keep in mind:
The link to the jQuery file must precede any programming that relies on jQuery. In other words, don’t put any other script tags before the <script> tag that loads jQuery.
Put your JavaScript programming after any CSS stylesheets (both linked, external stylesheets and internal stylesheets). Because jQuery programming often references styles from a stylesheet, you should put your JavaScript programming after the web browser has loaded any styles. A good rule of thumb is to put your JavaScript programming (all your <script> tags) after any other content inside the <head> tag, but before the closing </head> tag.
Add a JavaScript comment—for example, //end ready—after the }); that marks the end of the ready() function. For example:
$
(
document
).
ready
(
function
()
{
// your programming goes here
});
// end ready
Putting a comment at the end of the function makes it easy to identify the end of the program. As you’ll see later, jQuery often requires lots of little collections of this brace, parenthesis, and semicolon trio. By adding a comment after them, it’ll be much easier to identify which group of punctuation belongs to which part of your program.
Modifying Web Pages: An Overview
JavaScript gives you the power to change a web page before your very eyes. Using JavaScript, you can add pictures and text, remove content, or change the appearance of an element on a page instantly. In fact, dynamically changing a web page is the hallmark of the newest breed of JavaScript-powered websites. For example, Google Maps (http://maps.google.com/) provides access to a map of the world; when you zoom into the map or scroll across it, the page gets updated without the need to load a new web page. Similarly, when you mouse over a movie title at Netflix (www.netflix.com), an information bubble appears on top of the page providing more detail about the movie (see Figure 4-1). In both of these examples, JavaScript is changing the HTML that the web browser originally downloaded.
In this chapter, you’ll learn how to alter a web page using JavaScript. You’ll add new content, HTML tags and HTML attributes, and also alter content and tags that are already on the page. In other words, you’ll use JavaScript to generate new HTML and change the HTML that’s already on the page.
It may seem hard to believe, but, if you know how to create web pages with HTML and CSS, you already know a lot of what you need to effectively use JavaScript to create interactive websites. For example, the popular Datepicker plug-in for the jQuery UI project makes it easy for visitors to select a date on a form (for instance, as part of a flight or event scheduler). When a visitor clicks into a specially marked text field, a calendar pops up (see Figure 4-2). While the effect is really cool, and the calendar makes it especially easy to pick a date, JavaScript provides only the interactivity—the actual calendar is created with the same old HTML and CSS that you’re familiar with.
If you look under the hood of the calendar, you’ll find a series of HTML tags such as divs, a table, and <td> tags, with special classes and IDs (ui-datepicker-month, ui-datepicker-div, and so on) applied to them. A style sheet with class and ID styles adds color, typography, and formatting. In other words, you could create this same calendar yourself with HTML and CSS. JavaScript just makes the presentation interactive by making the calendar appear when a visitor clicks on a form field and disappear when the visitor selects a date.
So one way of thinking about modern JavaScript programming—especially as it applies to user interface design—is as a way to automate the creation of HTML and the application of CSS. In the Netflix example in Figure 4-1, JavaScript makes the pop-up information bubble appear when a visitor mouses over a movie, but the really fun part (the design of that info bubble) is simply a good use of HTML and CSS…stuff you already know how to do!
So a lot of what you’ll use JavaScript for is manipulating a web page by adding new content, changing the HTML of a page, or applying CSS to an element. Whenever you change the content, HTML, or CSS on a page—whether you’re adding a navigation bar complete with pop-up menus, creating a JavaScript-driven slide show, or simply making a page fade into view (as you did in the tutorial in Chapter 1)—you’ll perform two main steps.
Select an element on a page.
An element is any existing tag, and before you can do anything with that element, you need to select it using JavaScript (which you’ll learn how to do in this chapter). For example, to make a page fade into view, you first must select the page’s content (the <body> tag); to make a pop-up menu appear when you mouse over a button, you need to select that button. Even if you simply want to use JavaScript to add text to the bottom of a web page, you need to select a tag to insert the text inside, before, or after that tag.
Do something with the element.
OK, “do something” isn’t a very specific instruction. That’s because there’s nearly an endless number of things you can do with an element to alter the way your web page looks or acts. In fact, most of this book is devoted to teaching you different things to do to page elements. Here are a few examples:
Change a property of the element. When animating a <div> across a page, for example, you change that element’s position on the page.
Add new content. If, while filling out a web form, a visitor incorrectly fills out a field, it’s common to make an error message appear—“Please supply an email address,” for example. In this case, you’re adding content somewhere in relation to that form field.
Remove the element. In the Netflix example pictured in Figure 4-1, the pop-up bubble disappears when you mouse off the movie title. In this case, JavaScript removes that pop-up bubble from the page.
Extract information from the element. Other times, you’ll want to know something about the tag you’ve selected. For example, to validate a text field, you need to select that text field, then find out what text was typed into that field—in other words, you need to get the value of that field.
Add/remove a class attribute. Sometimes you’ll want an element on a page to change appearance: the text in a paragraph to turn blue, or the background color of a text field to turn red to indicate an error. While JavaScript can make these visual changes, often the easiest way is to simply apply a class and let a web browser make those visual changes based on a CSS style from a style sheet. To change the text of a paragraph to blue, for example, you can simply create a class style with blue text color, and use JavaScript to apply the class to the paragraph dynamically.
Many times, you’ll do several of the things listed above at the same time. For example, say you want to make sure a visitor doesn’t forget to type her email address into a form field. If she tries to submit the form without her email address, you can notify her. This task might involve first finding out if she’s typed anything into that text field (extracting information from the element), printing an error message (“adding new content”) if she doesn’t, and highlighting that form field (by adding a class to the text field).
Selecting a page element is the first step. To understand how to identify and modify a part of a page using JavaScript, you first need to get to know the Document Object Model.
Understanding the Document Object Model
When a web browser loads an HTML file, it displays the contents of that file on the screen (appropriately styled with CSS, of course). But that’s not all the web browser does with the tags, attributes, and contents of the file: It also creates and memorizes a “model” of that page’s HTML. In other words, the web browser remembers the HTML tags, their attributes, and the order in which they appear in the file—this representation of the page is called the Document Object Model, or DOM for short.
The DOM provides the information needed for JavaScript to communicate with the elements on the web page. The DOM also provides the tools necessary to navigate through, change, and add to the HTML on the page. The DOM itself isn’t actually JavaScript—it’s a standard from the World Wide Web Consortium (W3C) that most browser manufacturers have adopted and added to their browsers. The DOM lets JavaScript communicate with and change a page’s HTML.
To see how the DOM works, take look at this very simple web page:
<!DOCTYPE HTML>
<html>
<head>
<meta
charset=
"UTF-8"
>
<title>
A web page</title>
</head>
<body
class=
"home"
>
<h1
id=
"header"
>
A headline</h1>
<p>
Some<strong>
important</strong>
text</p>
</body>
</html>
On this and all other websites, some tags wrap around other tags—like the <html> tag, which surrounds all other tags, or the <body> tag, which wraps around the tags and contents that appear in the browser window. You can represent the relationship between tags with a kind of family tree (see Figure 4-3). The <html> tag is the “root” of the tree—like the great-great-great granddaddy of all of the other tags on the page—while other tags represent different “branches” of the family tree; for example, the <head> and <body> tags, which each contain their own set of tags.
In addition to HTML tags, web browsers also keep track of the text that appears inside a tag (for example, “A headline” inside the <h1> tag in Figure 4-3), as well as the attributes that are assigned to each tag (the class attribute applied to the <body> and <h1> tags in Figure 4-3). In fact, the DOM treats each of these—tags (also called elements), attributes, and text—as individual units called nodes.
JavaScript provides several ways to select elements on a page so you can do something to them—like make them fade out of view or animate across the page. The document.getElementById() method lets you select an element with a particular ID applied to its HTML. So if you have a <div> tag with the ID banner applied to it—<div id=“banner”>—you could select that div like this:
document
.
getElementById
(
'banner'
);
Likewise, the document.getElementsByTagName() method selects every instance of a particular tag (document.getElementsByTagName(‘a’), for example, selects all anchor tags (links) on a page); and some browsers support methods for selecting all elements with a particular class or using a CSS selector to select page elements.
Selecting Page Elements: The jQuery Way
As you read on the opposite page, web browsers provide two primary methods for selecting an element on a web page—document.getElementById() and document.getElementsByTagName(). Unfortunately, these two methods don’t provide the control needed to make more subtle kinds of selections. For example, if you want to select every <a> tag with a class of navButton, you first need to select every tag, and then go through each and find only the ones that have the proper class name.
Fortunately, jQuery offers a very powerful technique for selecting and working on a collection of elements—CSS selectors. That’s right, if you’re used to using Cascading Style Sheets to style your web pages, you’re ready to use jQuery. A CSS selector is simply the instruction that tells a web browser which tag the style applies to. For example, h1 is a basic element selector, which applies a style to every <h1> tag, while .copyright, is a class selector, which styles any tag that has a class attribute of copyright like this:
<p
class="copyright"
>Copyright, 2011</p>
With jQuery, you select one or more elements using a special command called the jQuery object. The basic syntax is like this:
$
(
'selector'
)
You can use nearly all CSS 2.1 and many CSS 3 selectors when you create a jQuery object (even if the browser itself doesn’t understand the particular selector—like IE with certain CSS 3 selectors). For example, if you want to select a tag with a specific ID of banner in jQuery, you can write this:
$
(
'#banner'
)
The #banner is the CSS selector used to style a tag with the ID name banner—the # part indicates that you’re identifying an ID. Of course, once you select one or more elements, you’ll want to do something with them—jQuery provides many tools for working with elements. For example, say you want to change the HTML inside an element; you can write this:
$
(
'#banner'
).
html
(
'<h1>JavaScript was here</h1>'
);
You’ll learn more about how to work with page elements using jQuery starting on Adding Content to a Page, and throughout the rest of this book. But first, you need learn more about using jQuery to select page elements.
Note
The latest versions of most browsers now include the ability to select elements by class name and by using CSS selectors. However, since support for this isn’t the same across the browsers used world-wide, jQuery helps out by making sure that your selections work even in that old antique, IE6.
Basic Selectors
Basic CSS selectors like IDs, classes, and element selectors make up the heart of CSS. They’re a great way to select a wide range of elements using jQuery.
Because reading about selectors isn’t the best way to gain an understanding of them, this book includes an interactive web page so you can test selectors. In the testbed folder of the book’s tutorial files, you’ll find a file named selectors.html. Open the file in a web browser. You can test various jQuery selectors by typing them into the selector box and clicking Apply (see Figure 4-4).
Note
See Your First JavaScript Program for information on where to find the tutorial files for this book.
ID selectors
You can select any page element that has an ID applied to it using jQuery and a CSS ID selector. For example, say you have the following HTML in a web page:
<p
id=
"message"
>
Special message</p>
To select that element using the old DOM way, you’d write this:
var
messagePara
=
document
.
getElementById
(
'message'
);
The jQuery method looks like this:
var
messagePara
=
$
(
'#message'
);
Unlike with the DOM method, you don’t just use the ID name (‘message’); you have to use the CSS-syntax for defining an ID selector (‘#message’). In other words, you include the pound sign before the ID name, just as if creating a CSS style for that ID.
Element selectors
jQuery also has its own replacement for the getElementsByTagName() method. Just pass the tag’s name to jQuery. For example, using the old DOM method to select every <a> tag on the page, you’d write this:
var
linksList
=
document
.
getElementsByTagName
(
'a'
);
With jQuery, you’d write this:
var
linksList
=
$
(
'a'
);
Tip
jQuery supports an even wider range of selectors than are listed here. Although this book lists many useful ones, you can find a complete list of jQuery selectors at http://api.jquery.com/category/selectors/.
Class selectors
Another useful way of selecting elements is by class name. For example, suppose you want to create a navigation bar that includes drop-down menus; when a visitor mouses over one of the main navigation buttons, you want a drop-down menu to appear. You need to use JavaScript to control those menus, and you need a way to program each of the main navigation buttons to open a drop-down menu when someone mouses over the button.
Note
Because finding all elements with a particular class name is such a common task, the latest version of most browsers support a method to do that. But since not all browsers have a built-in way to find elements of a specific class (like IE8 and earlier), a library like jQuery, which takes the different browsers into account, is invaluable.
One technique is to add a class—like navButton—to each of the main navigation bar links, and then use JavaScript to search for links with just that class name and apply all of the magical menu-opening power to those links (you’ll learn how to do that, by the way, on Basic, Animated Navigation Bar). This scheme may sound confusing, but the important point for now is that to make this navigation bar work, you need a way to select only the links with a specific class name.
Fortunately, jQuery provides an easy method to select all elements with the same class name. Just use a CSS class selector like this:
$
(
'.submenu'
)
Again, notice that you write the CSS class selector just like, well, a CSS class selector, with the period before the class name. Once you select those tags, you can manipulate them using jQuery. For example, to hide all tags with the class name of .submenu, you’d write this:
$
(
'.submenu'
).
hide
();
You’ll learn more about the jQuery hide() function on Basic Showing and Hiding, but for now, this example gives you a bit of an idea of how jQuery works.
Advanced Selectors
jQuery also lets you use more complicated CSS selectors to accurately pinpoint the tags you wish to select. Don’t worry too much about mastering these right now: Once you’ve read a few more chapters and gained a better understanding of how jQuery works and how to use it to manipulate a web page, you’ll probably want to turn back to this section and take another look.
Descendent selectors provide a way to target a tag inside another tag. For example, say you’ve created an unordered list of links and added an ID name of navBar to the list’s <ul> tag like this: <ul id=“navBar”>. The jQuery expression $(‘a’) selects all <a> tags on the page. However, if you want to select only the links inside the unordered list, you use a descendent selector like this:
$
(
'#navBar a'
)
Again, this syntax is just basic CSS: a selector, followed by a space, followed by another selector. The selector listed last is the target (in this case, a), while each selector to the left represents a tag that wraps around the target.
Child selectors target a tag that’s the child of another tag. A child tag is the direct descendent of another tag. For example, in the HTML diagrammed in Figure 4-3, the <h1> and <p> tags are children of the <body> tag, but the <strong> tag is not (since it’s wrapped by the <p> tag). You create a child selector by first listing the parent element, followed by a >, and then the child element. For example, to select <p> tags that are the children of the <body> tag, you’d write this:
$
(
'body > p'
)
Adjacent sibling selectors let you select a tag that appears directly after another tag. For example, say you have an invisible panel that appears when you click a tab. In your HTML, the tab might be represented by a heading tag (say <h2>), while the hidden panel is a <div> tag that follows the header. To make the <div> tag (the panel) visible, you’ll need a way to select it. You can easily do so with jQuery and an adjacent sibling selector:
$
(
'h2 + div'
)
To create an adjacent sibling selector, just add a plus sign between two selectors (which can be any type of selector: IDs, classes, or elements). The selector on the right is the one to select, but only if it comes directly after the selector on the left.
Attribute selectors let you select elements based on whether the element has a particular attribute, and even check to make sure the attribute matches a specific value. With an attribute selector, you can find <img> tags that have the alt attribute set, or even match an <img> tag that has a particular alt text value. Or you could find every link tag that points outside your site, and add code to just those links, so they’ll open in new windows.
You add the attribute selector after the name of the element whose attribute you’re checking. For example, to find <img> tags that have the alt attribute set, you write this:
$
(
'img[alt]'
)
[attribute] selects elements that have the specified attribute assigned in the HTML. For example, $('a[href]') locates all <a> tags that have an href attribute set. Selecting by attribute lets you exclude named anchors—<a name=“placeOnPage”></a>—that are simply used as in-page links.
[attribute=“value”] selects elements that have a particular attribute with a specific value. For example, to find all text boxes in a form, you can use this:
$
(
'input[type="text"]'
)
Since most form elements share the same tag—<input>—the only way to tell the type of form element is to check its type attribute (selecting form elements is so common that jQuery includes specific selectors just for that purpose, as described on Selecting Form Elements).
[attribute^=“value”] matches elements with an attribute that begins with a specific value. For example, if you want to find links that point outside your site, you can use this code:
$
(
'a[href^="http://"]'
)
Notice that the entire attribute value doesn’t have to match just the beginning. So href^=http:// matches links that point to http://www.yahoo.com, http://www.google.com, and so on. Or you could use this selector to identify mailto: links like this:
$
(
'a[href^="mailto:"]'
)
[attribute$=“value”] matches elements whose attribute ends with a specific value, which is great for matching file extensions. For example, with this selector, you can locate links that point to PDF files (maybe to use JavaScript to add a special PDF icon, or dynamically generate a link to Adobe.com so your visitor can download the Acrobat Reader program). The code to select links that point to PDF files looks like this:
$
(
'a[href$=".pdf"]'
)
[attribute*=“value”] matches elements whose attribute contains a specific value anywhere in the attribute. For example, you can find any type of link that points to a particular domain. For example, here’s how to find a link that points to missingmanuals.com (http://missingmanuals.com):
$
(
'a[href*="missingmanuals.com"]'
)
This selector provides the flexibility to find not only links that point to http://www.missingmanuals.com, but also http://missingmanuals.com and http://www.missingmanuals.com/library.html.
Note
jQuery has a set of selectors that are useful when working with forms. They let you select elements such as text fields, password fields, and selected radio buttons. You’ll learn about these selectors on Selecting Form Elements.
jQuery Filters
jQuery also provides a way to filter your selections based on certain characteristics. For example, the :even filter lets you select every even element in a collection of elements. In addition, you can find elements that contain particular tags, specific text, elements that are hidden from view, and even elements that do not match a particular selector. To use a filter, you add a colon followed by the filter’s name after the main selector. For example, to find every even row of a table, write your jQuery selector like this:
$
(
'tr:even'
)
This code selects every even <tr> tag. To narrow down the selection, you may want to just find every even table row in a table with class name of striped. You can do that like this:
$
(
'.striped tr:even'
)
Here’s how :even and other filters work:
:even and :odd select every other element in a group. These filters work a little counter-intuitively; just remember that a jQuery selection is a list of all elements that match a specified selector. In that respect, they’re kind of like arrays (see Arrays). Each element in a jQuery selection has an index number—remember that index values for arrays always start at 0 (see Accessing Items in an Array). So, since :even filters on even index values (like 0, 2, and 4), this filter actually returns the first, third, and fifth items (and so on) in the selection—in other words, it’s really selecting every other odd element! The :odd filter works the same except it selects every odd index number (1, 3, 5, and so on).
:first and :last select the first or the last element in a group. For example, if you wanted to select the first paragraph on a page, you’d type this:
$
(
'p:first'
);
And to select the last paragraph on a page, you’d type this:
$
(
'p:last'
);
You can use :not() to find elements that don’t match a particular selector type. For example, say you want to select every <a> tag except ones with a class of navButton. Here’s how to do that:
$
(
'a:not(.navButton)'
);
You give the :not() function the name of the selector you wish to ignore. In this case, .navButton is a class selector, so this code translates to “does not have the class of .navButton.” You can use :not() with any of the jQuery filters and with most jQuery selectors; so, for example, to find every link that doesn’t begin with http://, you can write this:
$
(
'a:not([href^="http://"])'
)
:has() finds elements that contain another selector. For example, say you want to find all <li> tags, but only if they have an <a> tag inside them. You’d do that like this:
$
(
'li:has(a)'
)
This setup is different from a descendent selector, since it doesn’t select the <a>; it selects <li> tags, but only those <li> tags with a link inside them.
:contains() finds elements that contain specific text. For example, to find every link that says “Click Me!” you can create a jQuery object like this:
$
(
'a:contains(Click Me!)'
)
:hidden locates elements that are hidden, which includes elements that either have the CSS display property set to none (which means you won’t see them on the page), elements you hide using jQuery’s hide() function (discussed on Basic Showing and Hiding), elements with width and height values set to 0, and hidden form fields. (This selector doesn’t apply to elements whose CSS visibility property is set to invisible.) For example, say you’ve hidden several <div> tags; you can find them and then make them visible using jQuery, like this:
$
(
'div:hidden'
).
show
();
This line of code has no effect on <div> tags that are currently visible on the page. (You’ll learn about jQuery’s show() function on Basic Showing and Hiding.)
:visible is the opposite of :hidden. It locates elements that are visible on the page.
Understanding jQuery Selections
When you select one or more elements using the jQuery object—for example, $(‘#navBar a’)—you don’t end up with a traditional list of DOM nodes, like the ones you get if you use getElementById() or getElementsByTagName(). Instead, you get a special jQuery-only selection of elements. These elements don’t understand the traditional DOM methods; so, if you learned about the DOM in another book, you’ll find that none of the methods you learned there work with the jQuery object as-is. That may seem like a major drawback, but nearly all of the properties and methods of a normal DOM node have jQuery equivalents, so you can do anything the traditional DOM can do—only usually much faster and with fewer lines of code.
There are, however, two big conceptual differences between how the DOM works and how jQuery selections work. jQuery was built to make it a lot easier and faster to program JavaScript. One of the goals of the library is to let you do a lot of stuff with as few lines of code as possible. To achieve that, jQuery uses two unusual principles.
Automatic loops
Normally, when you’re using the DOM and you select a bunch of page elements, you then need to create a loop (Handling Repetitive Tasks with Loops) to go through each node selected and do something to that node. For example, if you want to select all the images in a page and then hide them—something you might do if you want to create a JavaScript-driven slideshow—you must first select the images and then create a loop to go through the list of images.
Because looping through a collection of elements is so common, jQuery functions have that feature built right in. In other words, when you apply a jQuery function to a selection of elements, you don’t need to create a loop yourself, since the function does it automatically.
For example, to select all images inside a <div> tag with an ID of slideshow and then hide those images, you write this in jQuery:
$
(
'#slideshow img'
).
hide
();
The list of elements created with $(‘#slideshow img’) might include 50 images. The hide() function automatically loops through the list, hiding each image individually. This setup is so convenient (imagine the number of for loops you won’t have to write) that it’s surprising that this great feature isn’t just part of the JavaScript.
Chaining functions
Sometimes you’ll want to perform several operations on a selection of elements. For example, say you want to set the width and height of a <div> tag (with an ID of popUp) using JavaScript. Normally, you’d have to write at least two lines of code. But jQuery lets you do so with a single line:
$
(
'#popUp'
).
width
(
300
).
height
(
300
);
jQuery uses a unique principle called chaining, which lets you add functions one after the other. Each function is connected to the next by a period, and operates on the same jQuery collection of elements as the previous function. So the code above changes the width of the element with the ID popUp, and changes the height of the element. Chaining jQuery functions lets you concisely carry out a large number of actions. For example, say you not only want to set the width and height of the <div> tag, but also want to add text inside the <div> and make it fade into view (assuming it’s not currently visible on the page). You can do that very succinctly like this:
$
(
'#popUp'
).
width
(
300
).
height
(
300
).
text
(
'Hi!'
).
fadeIn
(
1000
);
This code applies four jQuery functions—width(), height(), text(), and fadeIn()—to the tag with an ID name of popUp.
Tip
A long line of chained jQuery functions can be hard to read, so some programmers break it up over multiple lines like this:
$
(
'#popUp'
).
width
(
300
)
.
height
(
300
)
.
text
(
'Message'
)
.
fadeIn
(
1000
);
As long as you only add a semicolon on the last line of the chain, the JavaScript interpreter treats the lines as a single statement.
The ability to chain functions is pretty unusual and is a specific feature of jQuery—in other words, you can’t add non-jQuery functions (either ones you create or built-in JavaScript functions) in the chain.
Adding Content to a Page
jQuery provides many functions for manipulating elements and content on a page, from simply replacing HTML, to precisely positioning new HTML in relation to a selected element, to completely removing tags and content from the page.
Note
An example file, content_functions.html, located in the testbed tutorial folder, lets you take each of these jQuery functions for a test drive. Just open the file in a web browser, type some text in the text box, and click any of the boxes to see how each function works.
To study the following examples of these functions, assume you have a page with the following HTML:
<div
id=
"container"
>
<div
id=
"errors"
>
<h2>
Errors:</h2>
</div>
</div>
.html() can both read the current HTML inside an element and replace the current contents with some other HTML. You use the html() function in conjunction with a jQuery selection.
To retrieve the HTML currently inside the selection, just add .html() after the jQuery selection. For example, you can run the following command using the HTML snippet at the beginning of this section:
alert
(
$
(
'#errors'
).
html
());
This code creates an alert box with the text “<h2>Errors:</h2>” in it. When you use the html() function in this way, you can make a copy of the HTML inside a specific element and paste it into another element on a page.
If you supply a string as an argument to .html(), you replace the current contents inside the selection:
$
(
'#errors'
).
html
(
'<p>There are four errors in this form</p>'
);
This line of code replaces all of the HTML inside an element with an ID of errors. It would change the example HTML snippet to:
<div
id=
"container"
>
<div
id=
"errors"
>
<p>
There are four errors in this form</p>
</div>
</div>
Notice that it replaces the <h2> tag that was already there. You can avoid replacing that HTML using other functions listed below.
.text() works like .html() but it doesn’t accept HTML tags. It’s useful when you want to replace the text within a tag. For example, in the code at the beginning of this section, you’ll see an <h2> tag with the text “Errors:” in it. Say, after running a program to check to see if there were any errors in the form, you wanted to replace the text “Errors:” with “No errors found”, you could use this code:
$
(
'#errors h2'
).
text
(
'No errors found'
);
The <h2> tag stays in place; only the text inside changes. jQuery encodes any HTML tags that you pass to the text() function, so that <p> is translated to <p>. This can come in handy if you want you to actually display the brackets and tag names on the page. For example, you can use it to display example HTML code for other people to view.
.append() adds HTML as the last child element of the selected element. For example, say you select a <div> tag, but instead of replacing the contents of the <div>, you just want to add some HTML before the closing </div> tag. The .append() function is a great way to add an item to the end of a bulleted (<ul>) or numbered (<ol>) list. As an example, say you run the following code on a page with the HTML listed at the beginning of this section:
$
(
'#errors'
).
append
(
'<p>There are four errors in this form</p>'
);
After this function runs, you end up with HTML like this:
<div
id=
"container"
>
<div
id=
"errors"
>
<h2>
Errors:</h2>
<p>
There are four errors in this form</p>
</div>
</div>
Notice that the original HTML inside the <div> remains the same, and the new chunk of HTML is added after it.
.prepend() is just like .append(), but adds HTML directly after the opening tag for the selection. For example, say you run the following code on the same HTML listed previously:
$
(
'#errors'
).
prepend
(
'<p>There are four errors in this form</p>'
);
After this prepend() function, you end up with the following HTML:
<div
id=
"container"
>
<div
id=
"errors"
>
<p>
There are four errors in this form</p>
<h2>
Errors:</h2>
</div>
</div>
Now the newly added content appears directly after the <div>’s opening tag.
If you want to add HTML just outside of a selection, either before the selected element’s opening tag or directly after the element’s closing tag, use the .before() or .after() functions. For example, it’s common practice to check a text field in a form to make sure that the field isn’t empty when your visitor submits the form. Assume that the HTML for the field looks like the following before the form is submitted:
<input
type=
"text"
name=
"userName"
id=
"userName"
>
Now suppose that when the visitor submits the form, this field is empty. You can write a program that checks the field and then adds an error message after the field. To add the message after this field (don’t worry right now about how you actually check that the contents of form fields are correct—you’ll find out on Form Validation), you can use the .after() function like this:
$
(
'#userName'
).
after
(
'<span class="error">User name required</span>'
);
That line of code makes the web page show the error message, and the HTML component would look like this:
<input
type=
"text"
name=
"userName"
id=
"userName"
>
<span
class=
"error"
>
User name required</span>
The .before() function simply puts the new content before the selected element.
Note
The functions listed in this section—html(), text(), and so on—are the most popular ways of adding and altering content on a page but they’re not the only ones. You can find more functions at http://api.jquery.com/category/manipulation/.
Replacing and Removing Selections
At times you may want to completely replace or remove a selected element. For example, say you’ve created a pop-up dialog box using JavaScript (not the old-fashioned alert() method, but a more professional-looking dialog box that’s actually just an absolutely-positioned <div> floating on top of the page). When the visitor clicks the “Close” button on the dialog box, you naturally want to remove the dialog box from the page. To do so, you can use the jQuery remove() function. Say the pop-up dialog box had an ID of popup; you can use the following code to delete it:
$
(
'#popup'
).
remove
();
The .remove() function isn’t limited to just a single element. Say you want to remove all <span> tags that have a class of error applied to them; you can do this:
$
(
'span.error'
).
remove
();
You can also completely replace a selection with new content. For example, suppose you have a page with photos of the products your company sells. When a visitor clicks on an image of a product, it’s added to a shopping cart. You might want to replace the <img> tag with some text when the image is clicked (“Added to cart,” for example). You’ll learn how to make particular elements react to events (like an image being clicked) in the next chapter, but for now just assume there’s an <img> tag with an ID of product101 that you wish to replace with text. Here’s how you do that with jQuery:
$
(
'#product101'
).
replaceWith
(
<
p
>
Added
to
cart
<
/p>');
This code removes the <img> tag from the page and replaces it with a <p> tag.
Note
jQuery also includes a function named clone() that lets you make a copy of a selected element. You’ll see this function in action in the tutorial on Automatic Pull Quotes.
Setting and Reading Tag Attributes
Adding, removing, and changing elements isn’t the only thing jQuery is good at, and it’s not the only thing you’ll want to do with a selection of elements. You’ll often want to change the value of an element’s attribute—add a class to a tag, for example, or change a CSS property of an element. You can also get the value of an attribute—for instance, what URL does a particular link point to?
Classes
Cascading Style Sheets are a very powerful technology, letting you add all sorts of sophisticated visual formatting to your HTML. One CSS rule can add a colorful background to a page, while another rule might completely hide an element from view. You can create some really advanced visual effects simply by using JavaScript to remove, add, or change a class applied to an element. Because web browsers process and implement CSS instructions very quickly and efficiently, simply adding a class to a tag can completely change that tag’s appearance—even make it disappear from the page.
jQuery provides several functions for manipulating a tag’s class attribute:
addClass() adds a specified class to an element. You add the addClass() after a jQuery selection and pass the function a string, which represents the class name you wish to add. For example, to add the class externalLink to all links pointing outside your site, you can use this code:
$
(
'a[href^="http://"]'
).
addClass
(
'externalLink'
);
This code would take HTML like this:
<a
href=
"http://www.oreilly.com/"
>
And change it to the following:
<a
href=
"http://www.oreilly.com/"
class=
"externalLink"
>
For this function to be of any use, you’ll need to create a CSS class style beforehand and add it to the page’s style sheet. Then, when the JavaScript adds the class name, the web browser can apply the style properties from the previously defined CSS rule.
Note
When using the addClass() and removeClass() functions, you only supply the class name—leave out the period you normally use when creating a class selector. For example, addClass(‘externalLink’) is correct, but addClass(‘.externalLink’) is wrong.
This jQuery function also takes care of issues that arise when a tag already has a class applied to it—the addClass() function doesn’t eliminate the old classes already applied to the tag; the function just adds the new class as well.
Note
Adding multiple class names to a single tag is perfectly valid and frequently very helpful. Check out www.cvwdesign.com/txp/article/177/use-more-than-one-css-class for more information on this technique.
removeClass() is the opposite of addClass(). It removes the specified class from the selected elements. For example, if you wanted to remove a class named highlight from a <div> with an ID of alertBox, you’d do this:
$
(
'#alertBox'
).
removeClass
(
'highlight'
);
Finally, you may want to toggle a particular class—meaning add the class if it doesn’t already exist, or remove the class if it does. Toggling is a popular way to show an element in either an on or off state. For example, when you click a radio button, it’s checked (on); click it again, and the checkmark disappears (off).
Say you have a button on a web page that, when clicked, changes the <body> tag’s class. By so doing, you can add a complete stylistic change to a web page by crafting a second set of styles using descendent selectors. When the button is clicked again, you want the class removed from the <body> tag, so that the page reverts back to its previous appearance. For this example, assume the button the visitor clicks to change the page’s style has an ID of changeStyle and you want to toggle the class name altStyle off and on with each click of the button. Here’s the code to do that:
$
(
'#changeStyle'
).
click
(
function
()
{
$
(
'body'
).
toggleClass
(
'altStyle'
);
});
At this point, don’t worry about the first and third lines of code above; those have to do with events that let scripts react to actions—like clicking the button—that happen on a page. You’ll learn about events in the next chapter. The bolded line of code demonstrates the toggleClass() function; it either adds or removes the class altStyle with each click of the button.
Reading and Changing CSS Properties
jQuery’s css() function also lets you directly change CSS properties of an element, so instead of simply applying a class style to an element, you can immediately add a border or background color, or set a width or positioning property. You can use the css() function in three ways: to find the current value for an element’s CSS property, to set a single CSS property on an element, or to set multiple CSS properties at once.
To determine the current value of a CSS property, pass the name of the property to the css() function. For example, say you want to find the background color of a <div> tag with an ID of main:
var
bgColor
=
$
(
'#main'
).
css
(
'background-color'
);
After this code runs, the variable bgColor will contain a string with the element’s background color value.
Note
jQuery may not always return CSS values the way you expect. In the case of colors (like the CSS background color, or color properties), jQuery always returns either an rgb value like rgb(255, 0, 10) or, if there is any transparency in the color, an rgba color value like rgba(255,10,10,.5). jQuery returns RGB values regardless of whether the color in the stylesheet was defined using hexadecimal notation (#F4477A), RGB using percentages (rgb(100%,10%,0%), or HSL (hsl(72,100%,50%). In addition, jQuery doesn’t understand shorthand CSS properties like font, margin, padding, or border. Instead, you have to use the specific CSS properties like font-face, margin-top, padding-bottom, or border-bottom-width to access styles that can be combined in CSS shorthand. Finally, jQuery translates all unit values to pixels, so even if you use CSS to set the <body> tag’s font-size to 150%, jQuery returns a pixel value when checking the font-size property.
The css() function also lets you set a CSS property for an element. To use the function this way, you supply two arguments to the function: the CSS property name and a value. For example, to change the font size for the <body> tag to 200% size, you can do this:
$
(
'body'
).
css
(
'font-size'
,
'200%'
);
The second argument you supply can be a string value, like ‘200%’, or a numeric value, which jQuery translates to pixels. For example, to change the padding inside all of the tags with a class of .pullquote to 100px, you can write this code:
$
(
'.pullquote'
).
css
(
'padding'
,
100
);
In this example, jQuery sets the padding property to 100 pixels.
Note
When you set a CSS property using jQuery’s .css() function, you can use the CSS shorthand method. For example, here’s how you could add a black, one-pixel border around all paragraphs with a class of highlight:
$
(
'p.highlight'
).
css
(
'border'
,
'1px solid black'
);
It’s often useful to change a CSS property based on its current value. For example, say you want to add a “Make text bigger” button on a web page, so when a visitor clicks the button, the page’s font-size doubles. To make that happen, you read the value, and then set a new value. In this case, you first determine the current font-size and then set the font-size to twice that value. It’s a little trickier than you might think. Here’s the code, and a full explanation follows:
var
baseFont
=
$
(
'body'
).
css
(
'font-size'
);
baseFont
=
parseInt
(
baseFont
,
10
);
$
(
'body'
).
css
(
'font-size'
,
baseFont
*
2
);
The first line retrieves the <body> tag’s font-size value—the returned value is in pixels and is a string like this: ‘16px’. Since you want to double that size—multiplying it by 2—you must convert that string to a number by removing the “px” part of the string. The second line accomplishes that using the JavaScript parseInt() method discussed on Changing a String to a Number. That function essentially strips off anything following the number, so after line 2, baseFont contains a number, like 16. Finally, the third line resets the font-size property by multiplying the baseFont value by 2.
Changing Multiple CSS Properties at Once
If you want to change more than one CSS property on an element, you don’t need to resort to multiple uses of the .css() function. For example, if you want to dynamically highlight a <div> tag (perhaps in reaction to an action taken by a visitor), you can change the <div> tag’s background color and add a border around it, like this:
$
(
'#highlightedDiv'
).
css
(
'background-color'
,
'#FF0000'
);
$
(
'#highlightedDiv'
).
css
(
'border'
,
'2px solid #FE0037'
);
Another way is to pass what’s called an object literal to the .css() function. Think of an object literal as a list of property name/value pairs. After each property name, you insert a colon (:) followed by a value; each name/value pair is separated by a comma, and the whole shebang is surrounded by braces—{}. Thus, an object literal for the two CSS property values above looks like this:
{
'background-color'
:
'#FF0000'
,
'border'
:
'2px solid #FE0037'
}
Because an object literal can be difficult to read if it’s crammed onto a single line, many programmers break it up over multiple lines. The following is functionally the same as the previous one-liner:
{
'background-color'
:
'#FF0000'
,
'border'
:
'2px solid #FE0037'
}
The basic structure of an object literal is diagrammed in Figure 4-5.
Warning
When creating an object literal, make sure to separate each name/value pair by adding a comma after the value (for instance, in this example, the comma goes after the value ‘#FF0000’. However, the last property/value pair should not have a comma after it, since no property/value pair follows it. If you do add a comma after the last value, some web browsers (including Internet Explorer) will generate an error.
To use an object literal with the css() function, just pass the object to the function like this:
$
(
'#highlightedDiv'
).
css
({
'background-color'
:
'#FF0000'
,
'border'
:
'2px solid #FE0037'
});
Study this example closely, because it looks a little different from what you’ve seen so far, and because you’ll be encountering lots of code that looks like it in future chapters. The first thing to notice is that this code is merely a single JavaScript statement (essentially just one line of code)—you can tell because the semicolon that ends the statement doesn’t appear until the last line. The statement is broken over four lines to make the code easier to read.
Next, notice that the object literal is an argument (like one piece of data) that’s passed to the css() function. So in the code css({, the opening parenthesis is part of the function, while the opening { marks the beginning of the object. The three characters in the last line break down like this: } is the end of the object and the end of the argument passed to the function; ) marks the end of the function, the last parenthesis in css(); and ; marks the end of the JavaScript statement.
And if all this object literal stuff is hurting your head, you’re free to change CSS properties one line at a time, like this:
$
(
'#highlightedDiv'
).
css
(
'background-color'
,
'#FF0000'
);
$
(
'#highlightedDiv'
).
css
(
'border'
,
'2px solid #FE0037'
);
Or, a better method is to use jQuery’s built-in chaining ability (Chaining functions). Chaining is applying several jQuery functions to a single collection of elements by adding that function to the end of another function, like this:
$
(
'#highlightedDiv'
).
css
(
'background-color'
,
'#FF0000'
)
.
css
(
'border'
,
'2px solid #FE0037'
);
This code can be translated as: find an element with an ID of highlightedDiv and change its background color, then change its border color. Chaining provides better performance than making the selection—$(‘#highlightedDiv’)—twice as in the code above, because each time you make a selection you make the web browser run all of the jQuery code for selecting the element. Thus, this code is not optimal.
$
(
'#highlightedDiv'
).
css
(
'background-color'
,
'#FF0000'
);
$
(
'#highlightedDiv'
).
css
(
'border'
,
'2px solid #FE0037'
);
This code forces the browser to select the element, change its CSS, select the element a second time (wasting processor time), and apply CSS again. Using the chaining method, the browser only needs to select the element a single time and then run the CSS function twice; selecting the element once is faster and more efficient.
Reading, Setting, and Removing HTML Attributes
Since changing classes and CSS properties using JavaScript are such common tasks, jQuery has built-in functions for them. But the addClass() and css() functions are really just shortcuts for changing the HTML class and style attributes. jQuery includes general-purpose functions for handling HTML attributes—the attr() and removeAttr() functions.
The attr() function lets you read a specified HTML attribute from a tag. For example, to determine the current graphic file a particular <img> points to, you pass the string ‘src’ (for the <img> tag’s src property) to the function:
var
imageFile
=
$
(
'#banner img'
).
attr
(
'src'
);
The attr() function returns the attributes value as it’s set in the HTML. This code returns the src property for the first <img> tag inside another tag with an ID of banner, so the variable imageFile would contain the path set in the page’s HTML: for instance, ‘images/banner.png’ or ‘http://www.thesite.com/images/banner.png’.
Note
When passing an attribute name to the .attr() function, you don’t need to worry about the case of the attribute name—href, HREF, or even HrEf will work.
If you pass a second argument to the attr() function, you can set the tag’s attribute. For example, to swap in a different image, you can change an <img> tag’s src property like this:
$
(
'#banner img'
).
attr
(
'src'
,
'images/newImage.png'
);
If you want to completely remove an attribute from a tag, use the removeAttr() function. For example, this code removes the bgColor property from the <body> tag:
$
(
'body'
).
removeAttr
(
'bgColor'
);
Acting on Each Element in a Selection
As discussed on Understanding jQuery Selections, one of the unique qualities of jQuery is that most of its functions automatically loop through each item in a jQuery selection. For example, to make every <img> on a page fade out, you only need one line of JavaScript code:
$
(
'img'
).
fadeOut
();
The .fadeOut() function causes an element to disappear slowly, and when attached to a jQuery selection containing multiple elements, the function loops through the selection and fades out each element. There are plenty of times when you’ll want to loop through a selection of elements and perform a series of actions on each element. jQuery provides the .each() function for just this purpose.
For example, say you want to list of all of the external links on your page in a bibliography box at the bottom of the page, perhaps titled “Other Sites Mentioned in This Article.” (OK, you may not ever want to do that, but just play along.) Anyway, you can create that box by:
Retrieving all links that point outside your site.
Getting the HREF attribute of each link (the URL).
Adding that URL to the other list of links in the bibliography box.
jQuery doesn’t have a built-in function that performs these exact steps, but you can use the each() function to do it yourself. It’s just a jQuery function, so you slap it on at the end of a selection of jQuery elements like this:
$
(
'
selector
'
).
each
();
Anonymous Functions
To use the each() function, you pass a special kind of argument to it—an anonymous function. The anonymous function is simply a function containing the steps that you wish to perform on each selected element. It’s called anonymous because, unlike the functions you learned to create on Functions: Turn Useful Code Into Reusable Commands, you don’t give it a name. Here’s an anonymous function’s basic structure:
function
()
{
//code goes here
}
Because there’s no name, you don’t have a way to call the function. For example, with a regular named function, you use its name with a set of parentheses like this: calculateSalesTax( );. Instead, you use the anonymous function as an argument that you pass to another function (strange and confusing, but true!). Here’s how you incorporate an anonymous function as part of the each() function:
$
(
'
selector
'
).
each
(
function
()
{
// code goes in here
}
);
Figure 4-6 diagrams the different parts of this construction. The last line is particularly confusing, since it includes three different symbols that close up three parts of the overall structure. The } marks the end of the function (that’s also the end of the argument passed to the each() function); the ) is the last part of the each() function; and ; indicates the end of a JavaScript statement. In other words, the JavaScript interpreter treats all of this code as a single instruction.
Now that the outer structure’s in place, it’s time to put something inside the anonymous function: all of the stuff you want to happen to each element in a selection. The each() function works like a loop—meaning the instructions inside the anonymous function will run once for each element you’ve retrieved. For example, say you have 50 images on a page and add the following JavaScript code to one of the page’s scripts:
$
(
'img'
).
each
(
function
()
{
alert
(
'I found an image'
);
});
Fifty alert dialog boxes with the message “I found an image” would appear. (That’d be really annoying, so don’t try this at home.)
Note
This may look somewhat familiar. As you saw on Adding jQuery to a Page, when you add jQuery to a page, you should use the document.ready() function to make sure a page’s HTML has loaded before the browser executes any of the JavaScript programming. That function also accepts an anonymous function as an argument:
$
(
document
).
ready
(
function
()
{
// programming goes inside this
// anonymous function
});
this and $(this)
When using the each() function, you’ll naturally want to access or set attributes of each element—for example, to find the URL for each external link. To access the current element through each loop, you use a special keyword called this. The this keyword refers to whatever element is calling the anonymous function. So the first time through the loop, this refers to the first element in the jQuery selection, while the second time through the loop, this refers to the second element.
The way jQuery works, this refers to a traditional DOM element, so you can access traditional DOM properties. But, as you’ve read in this chapter, the special jQuery selection lets you tap into all of the wonderful jQuery functions. So to convert this to its jQuery equivalent, you write $(this).
At this point, you’re probably thinking that all of this stuff is some kind of cruel joke intended to make your head swell. It’s not a joke, but it sure is confusing. To help make clear how to use $(this), take another look at the task described at the beginning of this section—creating a list of external links in a bibliography box at the bottom of a page.
Assume that the page’s HTML already has a <div> tag ready for the external links. For example:
<div
id=
"bibliography"
>
<h3>
web pages referenced in this article</h3>
<ul
id=
"bibList"
>
</ul>
</div>
The first step is to get a list of all links pointing outside your site. You can do so using an attribute selector (Advanced Selectors):
$
(
'a[href^="http://"]'
)
Now to loop through each link, we add the each() function:
$
(
'a[href^="http://"]'
).
each
()
Then add an anonymous function:
$
(
'a[href^="http://"]'
).
each
(
function
()
{
});
The first step in the anonymous function is to retrieve the URL for the link. Since each link has a different URL, you must access the current element each time through the loop. The $(this) keyword lets you do just that:
$
(
'a[href^=http://]'
).
each
(
function
()
{
var
extLink
=
$
(
this
).
attr
(
'href'
);
});
The code in the middle, bolded line does several things: First, it creates a new variable (extLink) and stores the value of the current element’s href property. Each time through the loop, $(this) refers to a different link on the page, so each time through the loop, the extLink variable changes.
After that, it’s just a matter of appending a new list item to the <ul> tag (see the HTML on this and $(this)), like this:
$
(
'a[href^=http://]'
).
each
(
function
()
{
var
extLink
=
$
(
this
).
attr
(
'href'
);
$
(
'#bibList'
).
append
(
'<li>'
+
extLink
+
'</li>'
);
});
You’ll use the $(this) keyword almost every time you use the each() function, so in a matter of time, $(this) will become second nature to you. To help you practice this concept, you’ll try it out in a tutorial.
Note
The example script used in this section is a good way to illustrate the use of the $(this) keyword, but it probably isn’t the best way to accomplish the task of writing a list of external links to a page. First, if there are no links, the <div> tag (which was hardcoded into the page’s HTML) will still appear, but it’ll be empty. In addition, if someone visits the page without JavaScript turned on, he won’t see the links, but will see the empty box. A better approach is to use JavaScript to create the enclosing <div> tag as well. You can find an example of that in the file bibliography.html accompanying the tutorials for this chapter.
Automatic Pull Quotes
In the final tutorial for this chapter, you’ll create a script that makes it very easy to add pull quotes to a page (like the one pictured in Figure 4-7). A pull quote is a box containing an interesting quote from the main text of a page. Newspapers, magazines, and websites all use these boxes to grab readers’ attention and emphasize an important or interesting point. But adding pull quotes manually requires duplicating text from the page and placing it inside a <div> tag, <span> tag, or some other container. Creating all that HTML takes time and adds extra HTML and duplicate text to the finished page. Fortunately, with JavaScript, you can quickly add any number of pull quotes to a page, adding just a small amount of HTML.
Overview
The script you’re about to create will do several things:
Locate every <span> tag containing a special class named pq (for pull quote).
The only work you have to do to the HTML of your page is to add <span> tags around any text you wish to turn into a pull quote. For example, suppose there’s a paragraph of text on a page and you want to highlight a few words from that paragraph in pull quote box. Just wrap that text in the <span> tag like this:
<span
class=
"pq"
>
...and that's how I discovered the Loch Ness monster.</span>
Duplicate each <span> tag.
Each pull quote box is essentially another span tag with the same text inside it, so you can use JavaScript to just duplicate the current <span> tag.
Remove the pq class from the duplicate <span> and add a new class pullquote.
The formatting magic—the box, larger text, border, and background color—that makes up each pull quote box isn’t JavaScript’s doing. The page’s style sheet contains a CSS class selector, .pullquote, that does all of that. So by simply using JavaScript to change the duplicate tags’ class name, you completely change the look of the new <span> tags.
Add the duplicate <span> tag to the page.
Finally, you add the duplicate <span> tag to the page. (Step 2 just makes a copy of the tag in the web browser’s memory, but doesn’t actually add that tag to the page yet. This gives you the opportunity to further manipulate the duplicated tag before displaying it for the person viewing the page.)
Programming
Now that you have an idea of what you’re trying to accomplish with this script, it’s time to open a text editor and make it happen.
Note
See the note on Note for information on how to download the tutorial files.
In a text editor, open the file pull-quote.html in the chapter04 folder.
You’ll start at the beginning by adding a link to the jQuery file.
Click in the empty line just above the closing </head> tag and type:
<script
src=
"../_js/jquery-1.7.2.min.js"
></script>
This loads the jQuery file from the site. Note that the name of the folder containing the jQuery file is _js (don’t forget the underscore character at the beginning). Next, you’ll add a set of <script> tags for your programming.
Press Enter (or Return) to create a new line below the jQuery code and add the code listed in bold below:
1
<script
src=
"../_js/jquery-1.7.2.min.js"
></script>
2<script>
3
4
</script>
Note
The line numbers to the left of each line of code are just for your reference. Don’t actually type them as part of the script on the web page.
Now add the document.ready() function.
Click on the empty line between the <script> tags and add the code in bold:
1
<script
src=
"../_js/jquery-1.7.2.min.js"
></script>
2<script>
3$(document).ready(function() {
4
5 }); // end ready
6</script>
The JavaScript comment // end ready is particularly helpful as your programs get longer and more complicated. On a long program, you’ll end up with lots of }); scattered throughout, each marking the end of an anonymous function and a function call. Putting a comment that identifies what the }); matches makes it much easier to later return to your code and understand what is going on.
Steps 1–4 cover the basic setup for any program you’ll write using jQuery, so make sure you understand what it does. Next, you’ll get into the heart of your program by selecting the <span> tags containing the text that should appear in the pullquote boxes.
Add the bolded code on line 4:
1
<script
src=
"../_js/jquery-1.7.2.min.js"
></script>
2<script>
3 $(document).ready(function() {4 $('span.pq')
5 }); // end ready 6</script>
The $(‘span.pq’) is a jQuery selector that locates every <span> tag with a class of pq applied to it. Next you’ll add the code needed to loop through each of these <span> tags and do something to them.
Add the bolded code on lines 4 and 6:
1
<script
src=
"../_js/jquery-1.7.2.min.js"
></script>
2<script>
3 $(document).ready(function() { 4 $('span.pq').each(function() {
5 6}); // end each
7 }); // end ready 8</script>
As discussed on Acting on Each Element in a Selection, .each() is a jQuery function that lets you loop through a selection of elements. The function takes one argument, which is an anonymous function.
Next you’ll start to build the function that will apply to each matching <span> tag on this page: Get started by creating a copy of the <span>.
Add the code listed in bold on line 5 below to the script:
1
<script
src=
"../_js/jquery-1.6.2.min.js"
></script>
2<script >
3 $(document).ready(function() { 4 $('span.pq').each(function() { 5var quote=$(this).clone();
6 }); // end each 7 }); // end ready 8</script>
This function starts by creating a new variable named quote, which contains a “clone” (just a copy) of the current <span> (see this and $(this) if you forgot what $(this) means). The jQuery .clone() function duplicates the current element, including all of the HTML within the element. In this case, it makes a copy of the <span> tag, including the text inside the <span> that will appear in the pull quote box.
Cloning an element copies everything, including any attributes applied to it. In this instance, the original <span> had a class named pq. You’ll remove that class from the copy.
Add the two lines of code listed in bold on lines 6 and 7 below to the script:
1
<script
src=
"../_js/jquery-1.7.2.min.js"
></script>
2<script>
3 $(document).ready(function() { 4 $('span.pq').each(function() { 5 var quote=$(this).clone(); 6quote.removeClass('pq');
7quote.addClass('pullquote');
8 }); // end each 9 }); // end ready 10</script>
As discussed on Classes, the removeClass() function removes a class name from a tag, while the .addClass() function adds a class name to a tag. In this case, we’re replacing the class name on the copy, so you can use a CSS class named .pullquote to format the <span> as a pull quote box.
Finally, you’ll add the <span> to the page.
Add the bolded line of code (line 8) to the script:
1
<script
src=
"../_js/jquery-1.7.2.min.js"
></script>
2<script>
3 $(document).ready(function() { 4 $('span.pq').each(function() { 5 var quote=$(this).clone(); 6 quote.removeClass('pq'); 7 quote.addClass('pullquote'); 8$(this).before(quote);
9 }); // end each 10 }); // end ready 11</script>
This line is the final piece of the function—up until this line, you’ve just been manipulating a copy of the <span> in the web browser’s memory. No one viewing the page would see it until the copy is actually added to the DOM.
In this case, you’re inserting the copy of the <span> tag, just before the one in your HTML. In essence, the page will end up with HTML sort of like this:
<span
class=
"pullquote"
>
...and that's how I discovered the Loch Ness monster.</span>
<span
class=
"pq"
>
...and that's how I discovered the Loch Ness monster.</span>
Although the text looks like it will appear duplicated side by side, the CSS formatting makes the pull quote box float to the right edge of the page.
Note
To achieve the visual effect of a pull quote box, the page has a CSS style that uses the CSS float property. The box is moved to the right edge of the paragraph in which the text appears, and the other text in the paragraph wraps around it. If you’re unfamiliar with this technique, you can learn about the CSS float property at http://css.maxdesign.com.au/floatutorial/. If you wish to examine the .pullquote style, just look in the head of the tutorial file. That style and all its properties are listed there.
At this point, all of the JavaScript is complete. However, you won’t see any pull quote boxes until you massage the HTML a bit.
Find the first <p> tag in the page’s HTML. Locate a sentence and wrap <span class=“pq”> </span> around it. For example:
<span
class=
"pq"
>
Nullam ut nibh sed orci tempor rutrum.</span>
You can repeat this process to add pull quotes to other paragraphs as well.
Save the file and preview it in a web browser.
The final result should look something like Figure 4-7. If you don’t see a pull quote box, make sure you added the <span> tag in step 10 correctly. Also, check out the tips on Tracking Down Errors for fixing a malfunctioning program. You can find a completed version of this tutorial in the file complete_pull-quote.html.
Get JavaScript & jQuery: The Missing Manual, 2nd Edition now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.