Extension Selectors
Many of jQuery's selectors are based on CSS3. Other selectors are jQuery extensions to CSS. These extension selectors include :animated, Attribute Not Equal, :button, :checkbox, :eq(), :even, :file, :first, :gt(), :has(), :header, :hidden, :image, :input, :last, :lt(), :odd, :parent, :password, :radio, :reset, :selected, :submit, :text, and :visible.
Queries that use extension selectors cannot take advantage of the performance boost offered by the native DOM querySelectorAll() method. querySelectorAll() returns a list of the elements within the document that match the specified group of selectors, using a depth-first pre-order traversal of the document's nodes on Firefox (and probably on other browsers as well).
jQuery's documentation recommends that you first select some elements using a pure CSS selector and then use jQuery's filter() method to achieve the best performance when using these extension selectors. For example, the following line sets the background color of all odd-indexed <li> elements to yellow:
$('li').filter(':odd').css('background-color', 'yellow');
Custom Selectors
Selectors that are prefixed with a colon character (such as in :first-child) are known as pseudo-class selectors. jQuery implements pseudo-class selectors as custom selectors, which are properties of the expr[':'] object (an alias for Sizzle.selectors.filters) according to the following syntax:
$.expr[':'].selectorName = function(elem, index, match) { /* ... */ }
This syntax specifies selectorName as a property of expr[':']. The anonymous function assigned to this property is invoked for each element in the current collection with the element, the element's index in the collection, and a match array as arguments. (The index and match array are optional.) It behaves as a filter, returning true to keep the element in the collection or false to remove the element from the collection.
Listing 5 presents an HTML document that demonstrates a pair of custom selectors.
Listing 5: Experimenting with custom selectors.
<html> <head> <title>Custom Selector Demo</title> <script type="text/javascript" src="https://code.jquery.com/jquery-1.7.2.min.js"> </script> </head> <body> <div style="border-style: dotted"> first division </div> <p> <div> second division </div> <p> <div style="border-style: dashed"> third division </div> <p> <div class="other" style="border-style: dashed"> fourth division </div> <script type="text/javascript"> $(function() { $.expr[":"].noborder = function(elem) { return $(elem).css("border-top-style") == "none"; } $("div:noborder").css("border-style", "solid"); $.expr[":"].noborder2 = function(elem, index, m) { return $(elem).css("border-top-style") != m[3]; } $("div.other:noborder2('ridge')").css("border-style", "ridge"); }); </script> </body> </html>
Listing 5 specifies four <div> elements with various border styles: dotted, none, dashed, and dashed. The listing also specifies a <script> element that defines a pair of custom selectors (noborder and noborder2) for changing these styles when they meet each selector's filtering criterion.
The noborder selector selects only those elements without border-top-style or border-style properties. The anonymous function for this selector accomplishes this task by comparing the element's border-top-style property against the value none (the default when neither border-style nor border-top-style is specified).
The noborder2 selector selects only those elements without a certain style of border, which is specified via an argument passed to the selector. The anonymous function obtains this argument from the third element of the match array. It then compares border-top-style's value with this argument, returning true when there is no match.
The following expression selects all class-less <div> elements without a border and gives them a solid border:
$("div:noborder").css("border-style", "solid");
This expression selects all <div> elements of class other that don't have a ridge border and gives them this border style:
$("div.other:noborder2(ridge)").css("border-style", "ridge")
Figure 5 shows the resulting page with dotted, solid, dashed, and ridge borders surrounding the four divisions.
Figure 5 A borderless division is given a solid border, and a dashed division is given a ridge border.
Conclusion
Selectors are a very useful jQuery feature that can save you much work. Now that you've become acquainted with this feature and jQuery's various selector categories, I encourage you to experiment with them. Have fun!