Programming
Article
By Earle Castledine

Selecting: The Core of jQuery

By Earle Castledine

Time is ticking, and deadlines wait for no one. The client has noted that people have been quoting incorrect celebrity IDs from the web site. This is because the celebrities’ names are all laid out in one big table and it’s difficult for users to line up a celebrity with the correct reference ID. Our client tells us that he wants every other row to be a light gray color so the users can easily find their favorite celebrity.

We have jQuery ready to do our bidding—it just needs us to choose a target for it. Selecting the elements you want to modify on the page is really the art of jQuery. One of the biggest differences between being a novice and ninja is the amount of time it takes you to grab the elements you want to play with!

Simple Selecting

Our task is to select alternate table rows on the celebrity table. How do we do this? When selecting with jQuery, your goal should be to be only as specific as required: you want to find out the most concise selector that returns exactly what you want to change. Let’s start by taking a look at the markup of the Celebrities table, shown below:

celebrities table

We could start by selecting every table row element on the entire page. To select by element type, you simply pass the element’s HTML name as a string parameter to the $ function. To select all table row elements (which are marked up with the <tr> tag), you would simply write:

$('tr')

Nothing Happens!

If you run this command, nothing will happen on the page. This is expected—after all, we’re just selecting elements. But there’s no need to worry; soon enough we’ll be modifying our selections in all sorts of weird and wonderful ways.

Similarly, if we wanted to select every paragraph, div element, h1 heading, or input box on the page, we would use these selectors accordingly:

$('p')

$('div')

$('h1')

$('input')

But we don’t want to change every table row on the celebrity page: just the rows in the table that have the celebrity data. We need to be a bit more specific, and select first the containing element that holds the list of celebrities. If you have a look at the HTML and at the image of the Celebrities table, you can see that the div that contains our celebrity table has an id of celebs, while the table itself has a class of data. We could use either of these to select the table.

jQuery borrows the conventions from CSS for referring to id and class names. To select by id, use the hash symbol (#) followed by the element’s id, and pass this as a string to the jQuery function:

$('#celebs')

You should note that the string we pass to the jQuery function is exactly the same format as a CSS id selector. Because ids should be unique, we expect this to only return one element. jQuery now holds a reference to this element.

Similarly, we can use a CSS class selector to select by class. We pass a string consisting of a period (.) followed by the element’s class name to the jQuery function:

$('.data')

Both of these statements will select the table but a class can be shared by multiple elements—and jQuery will happily select as many elements as we point it to. If there were multiple tables (or any other elements for that matter) that also had the class data, they’d all be selected. For that reason, we’ll stick to using the id for this one!

Can You Be More Specific?

Just like with CSS, we can select either $('.data') or the more specific $('table.data'). By specifying an element type in addition to the class, the selector will only return table elements with the class data—rather than all elements with the class data. Also, like CSS, you can add parent container selectors to narrow your selection even further.

Narrowing Down Our Selection

We’ve selected the table successfully, though the table itself is of no interest to us—we want every other row inside it. We’ve selected the containing element, and from that containing element we want to pick out all the descendants that are table rows: that is, we want to specify all table rows inside the containing table. To do this, we put a space between the ancestor and the descendant:

$('#celebs tr')

You can use this construct to drill down to the elements that you’re looking for, but for clarity’s sake try to keep your selectors as succinct as possible.

Let’s take this idea a step further. Say we wanted to select all span elements inside of p elements, which are themselves inside div elements—but only if those divs happen to have a class of fancy. We would use the selector:

$('div.fancy p span')

If you can follow this, you’re ready to select just about anything!

Testing Our Selection

Right, back to our task at hand. It feels like we’re getting closer, but so far we’ve just been selecting blindly with no way of knowing if we’re on the right path. We need a way of confirming that we’re selecting the correct elements. A simple way to achieve this is to take advantage of the length property. length returns the number of elements currently matched by the selector. We can combine this with the good ol’ trusty alert statement to ensure that our elements have been selected:

$(document).ready(function() {
  alert($('#celebs tr').length + ' elements!');
});

This will alert the length of the selection—7 elements—for the celebrity table. This result might be different from what you’d expect, as there are only six celebrities in the table! If you have a look at the HTML, you’ll see where our problem lies: the table header is also a tr, so there are seven rows in total. A quick fix involves narrowing down our selector to find only table rows that lie inside the tbody element:

$(document).ready(function() {
  alert($('#celebs tbody tr').length + ' elements!');
});

This will alert the correct length of 6 elements—the jQuery object is now holding our six celebrity table row elements.

If the alert shows 0, you’ll know there’s a mistake in your selector. A good way to troubleshoot this sort of issue is to reduce your selector to the smallest, simplest one possible.

In our example, we could simply write $('#celebs'), which would select just the div element and alert a length of 1. From here you can make your selectors more specific, and check that you’re selecting the correct number of elements as you go.

Filters

With the knowledge that we’ve successfully selected all of the table rows, narrowing our selection down to every other row is simple—because jQuery has a filter to do it. A filter removes certain items, and keeps only the ones we want. You’ll acquire a feel for what can be filtered as we work through some more examples, but for now we’ll just jump straight to the filter we need for our zebra stripes:

$(document).ready(function() {
  alert($('#celebs tbody tr:even').length + ' elements!');
});

Filters are attached to the item you want to filter (in this case, the table rows) and are defined by a colon, followed by the filter name. The :even filter used here keeps every even-indexed element in the selection and removes the rest, which is what we want. When we alert the selection length now, we see 3, as expected. All of our odd-numbered rows have been filtered out of the selection. There is a wide array of jQuery selector filters available to us: :odd (as you might expect), :first, :last, :eq() (for selecting, for example, the third element), and more. We’ll look at each of these in more detail as we need them.

Selecting Multiple Elements

One last trick for basic selecting is the ability to select multiple elements in a single statement. This is very useful, as we’ll often want to apply the same action to several elements in unrelated parts of the page. Separating the selector strings with commas allows you to do this. For example, if we wanted to select every paragraph, div element, h1 heading, and input box on the page, we’d use this selector:

$('p,div,h1,input')

Learning how to use all these different selectors together to access exactly the page elements you want is a big part of mastering jQuery. It’s also one of the most satisfying parts of using jQuery, since you can pack some fairly complex selection logic into a single short line of code!

Becoming a Good Selector

Selecting may seem quite easy and, up to a point, it is. But what we’ve covered so far has only just scratched the surface of selecting. In most cases the basics are all you’ll need: if you’re simply trying to target an element or a bunch of related elements, the element name, id, and class are the most efficient and easiest ways to achieve this.

When moving around the DOM from a given element, the situation becomes a little trickier. jQuery provides a myriad of selectors and actions for traversing the DOM. Traversing means traveling up and down the page hierarchy, through parent and child elements. You can add and remove elements as you go, applying different actions at each step—which lets you perform some mind-bogglingly complex actions in a single jQuery statement!

If you’re a wiz at CSS, you’ll already be familiar with a lot of the statements; they’re mostly borrowed directly from the CSS specification. But there are probably a few that you’re unfamiliar with, especially if you’ve yet to spend much time learning CSS3 selectors. Of course, we’ll be covering and learning advanced selection techniques as we implement them in our examples and demos. For this reason, any time you want to find out more about all the jQuery selectors available, you can just head over to the online documentation and browse away!

note:Want more?

Check out the book and buy it online at jQuery: Novice to Ninja, by Earle Castledine & Craig Sharkie

Recommended
Sponsors
The most important and interesting stories in tech. Straight to your inbox, daily. Get Versioning.
Login or Create Account to Comment
Login Create Account