- Requires: jQuery library, text editor and web browser
- Project time: 2 hours
A lot of developers who are new to jQuery get hung up by jQuery selectors. In this tutorial Jay Blanchard, author of the forthcoming book Applied jQuery, covers jQuery's selector syntax, how to optimise jQuery selectors and how to apply more advanced selector combinations to your markup elements
jQuery's selectors are where you typically first come into contact with the library. Those of you who have worked with CSS extensively will find jQuery's selectors to be very familiar because jQuery makes extensive use of CSS's syntax for selectors. Others who are less familiar with CSS development will undoubtedly learn something new about both jQuery and CSS selectors.
In this article I will show you jQuery's selector syntax, how to optimise jQuery selectors and how to apply more advanced selector combinations to your markup elements. Let's get the journey started with jQuery selector basics.
Learning the basics
If you're selecting an item by id there will only be one object in the array.
- <ul id="list">
- <li id="itemOne">First Item</li>
- <li id="itemTwo">Second Item</li>
- <li id="itemThree">Third Item</li>
- <li id="itemFour">Fourth Item</li>
$('#itemThree') selects only the third list item and itemThree will be the only element in the jQuery object array for this selector.
In many website designs, ids are not assigned to elements in a web page. If that is the case, how can you select a specific element as demonstrated above? Have a look at this list:
- <ul id="list">
- <li>First Item</li>
- <li>Second Item</li>
- <li>Third Item</li>
- <li>Fourth Item</li>
If you have more than one list in your web page, you'll need to be more specific with the selector if you're trying to match one item in one list. In the case of the list illustrated you could use $('#list li:eq(2)') or $('#list li:nth-child(3)') to get the third item.
You can wrap multiple elements as an array in the jQuery object by using group identifiers such as HTML tags or class names in a selector. Using $('.content') will gather all of the HTML elements having a class of content into a jQuery object array. Likewise, $('p') will wrap all paragraphs in the document into a single jQuery object.
One of the things that you really need to be aware of when using jQuery is that selectors are read from right-to-left by the jQuery selector engine, Sizzle (John Resig, sizzlejs.com). What this means is that lengthy selectors are more resource-intensive and may take additional time to perform. Have a look at the following HTML markup:
This is a rather trumped-up example but if you wanted to select the second list item in the second list, you might use the jQuery selector:
- $('.container .selection li:nth-child(2)')
The jQuery selector engine essentially says: "First find all list items that are the second children. Then see if they are contained in a class called selection. After that, check to see that selection is a descendant of container. If you have a lot of similarly nested items, this can create a lot of overhead because jQuery has to traverse the DOM (Document Object Model) tree each time the selector is used. It's better to be as specific as possible and in this case you could just use the id of the list item in your selector, $('#three').
Selectors with element identifiers having spaces between them are also known as descendant selectors. The selector used will find all descendants of the class container that have the class of selection, regardless of how far down the DOM tree selection is. If you want to make sure that selection is a direct child of container you would write the selector this way:
- $('.container > .selection li:nth-child(2)')
The greater-than symbol will force the selection engine to make sure that elements with the class selection are direct descendants of those items having the class container.
There may come a time where you have to use a lengthy selector or you may need to use a particular selector over and over again. A really good example of this is when you're working with tables full of data that need to be manipulated. An easy way to optimise the action is to cache the jQuery selector object by containing it in a variable:
- var cell7 = $('table tr td:nth-child(7));
Then you can use that variable over and over again to manipulate the element:
- cell7.css('font-weight', 'bold');
- var newValue = $(this).html() + 3.14;
Since the variable contains the wrapped object, you won't need to traverse the DOM again to get the data for that selector.
With an understanding of basic jQuery selectors it's time to turn your focus to some of the more advanced selector syntax.
Learning advanced selectors
Attribute selectors in jQuery offer regular expression-like functionality and can even be combined in ways that provide conditional functionality. I'll use this block of HTML markup to demonstrate:
If you want to select the divs where the class "starts with" yellow you would use the ^ (carat) symbol:
How about selecting all of the items that have classes beginning with yellow OR having the class triangle?
Here the ~ (tilde) signifies that the attribute selector should look for items where the class "contains the word" triangle. By separating the attribute selectors with a comma you are providing an OR condition to the search. If you remove the comma the AND condition is invoked and will not return any object because there's no element with the class of "yellow triangle". You can continue to chain together attribute selectors together when working with jQuery.
The jQuery attribute selectors will work with any recognised HTML attribute. These selectors give you the power to retrieve elements based on the value of the attribute by having filters applied to them. You can learn more about the attribute selectors by visiting api.jquery.com/category/selectors/attribute-selectors/ .
(If you want to play with the attribute selectors, I've set up a sample that you can manipulate and run at jsfiddle.net).
Using selectors with forms
You can use jQuery's attribute selectors for working with forms and these types of selectors are often perfect for achieving a particular effect such as clearing a form after it is submitted:
If you want to clear other input elements you can put additional attribute definitions into the selector:
Use caution, though! I've seen many a developer use the following selector and wonder why their form, buttons and all, empties out:
All of the form's input values will be cleared, including text on any submit or reset elements included in the form. It's a good lesson in being specific with your jQuery selectors.
There’ll be times when you will want specialised selectors to work with form elements. You can use the :checked pseudo-selector to select all checkboxes that are checked and the :input pseudo-selector to wrap all of the inputs in a form. Let's use the following form as an example:
Using $('form[name="myForm"] input:checked') will wrap the input with the checkbox having the CHECKED property. If you want to select all inputs from your form, and it is the only form on the page, you can use $(':input').
Finding out more
Now you've learned the jQuery selector syntax and seen ways to combine and connect the jQuery library's selectors, you're well on your way to start adding jQuery to your web projects.
To really hone your jQuery skills I'd encourage you to spend some time studying the wide array of selectors available for the library. You can do so on the jQuery site at api.jquery.com/category/selectors/.