Selecting elements using attributes

Attribute selectors are extremely powerful and allow you to select elements based on their attributes. You can easily recognize these selectors because they’re wrapped with square brackets (for example, [selector]).

To see them in action, let’s take another look at a portion of the lab page:

<ul>
   <li>
      <a href="http://jquery.com">jQuery supports</a>
      <ul>
         <li><a href="css1">CSS1</a></li>
         <li><a href="css2">CSS2</a></li>
         <li><a href="css3">CSS3</a></li>
         <li>Basic XPath</li>
      </ul>
   </li>
</ul>

What usually makes the link pointing to an external site unique is the http:// at the beginning of the string value for the link’s href attribute. Actually, an external link may also be prefixed by https://ftp://, and many other protocols. Besides, a link pointing to a page of the same website might still start with http://. But for the sake of simplicity we’ll take into account http:// only and we’ll pretend that internal links use only relative paths.

In CSS, you could select links that have an href value starting with http:// with the following selector:

a[href^='http://']

Using jQuery, the latter can be employed in a statement like the following:

var $externalLinks = $("a[href^='http://']");

This matches all links with an href value beginning with the exact string http://. The caret character (^) is used to specify that the match has to occur at the beginning of a value. Because this is the same character used by most regular expression processors to signify matching at the beginning of a candidate string, it should be easy to remember.

Visit the lab page again (from which the previous HTML fragment was lifted), type a[href^='http://'] into the text box, and click Apply. Note that only the jQuery link is highlighted.

Single and double quotes

Pay attention to single and double quotes when you use the attribute selectors. A wrong combination of the latter will result in an invalid statement. If your style of code adopts the use of double quotes for strings and you want to use the same quotes for wrapping the attributes value, you must escape them. If you feel it’s easier for you to read a selection without escaped characters, you can mix the quote types. Using the selector a[href^="http://"] will result in the following equivalent statements:

$("a[href^=\"http://\"]");
$('a[href^=\'http://\']');
$("a[href^='http://']");
$('a[href^="http://"]');

Now imagine you want all the links but those pointing to the jQuery website’s homepage. Using our lovely library, you can write

$("a[href!='http://jquery.com']")

This statement, using the “not equal attribute” selector, gives you the expected result. Because this selector isn’t part of the CSS specifications, behind the scenes jQuery can’t take advantage of the native querySelectorAll() method, so this results in a slower execution.

These symbols can’t be combined with other ones to create even more powerful selectors. For example, if you want to select all links but the externals (assuming only those starting with http://), you can’t write

$("a[href!^='http://']");

At this point you may think that selecting elements by their attribute is possible only in conjunction with the Element selector. But this isn’t the case. You can use whatever selector you like, and even no other selectors at all, resulting in a selector like [href^='http://']. In this case, the use of the Universal selector (*) is implicitly assumed.

There are other ways to use attribute selectors. To match an element—for example, a form—that possesses a specific attribute, regardless of its value, you can use

form[method]

This matches any <form> that has an explicit method attribute.

To match a specific attribute value, you use something like

input[type='text']

This selector matches all input elements with a type of text.

You’ve already seen the “match attribute at beginning” selector in action. Here’s another example:

div[title^='my']

This selects all div elements with a title attribute whose value begins with my.

What about an “attribute ends with” selector? Coming right up:

a[href$='.pdf']

This is a useful selector for locating all links that reference PDF files.

And here’s a selector, called “attribute contains,” for locating elements whose attributes contain arbitrary strings anywhere in the attribute value:

a[href*='jquery.com']

As you’d expect, this selector matches all a elements that reference the jQuery site.

Another selector is the “contain prefix.” It selects elements with a given attribute’s value equal to a specified string or equal to a specified string followed by a hyphen. If you write

div[class|='main']

this selector will find all the <div>s having class="main" or having a class name starting with main-, like class="main-footer".

The last selector we’re going to discuss is similar to the previous one, except it’s used to search for a word within an attribute’s value. Let’s say you’re using the HTML5 data-* attribute—for example, data-technologies—to specify a list of values in some <span>s of your page. You want to perform a search to find if one of them contains the value “javascript”. You can perform this selection using the following selector:

span[data-technologies~="javascript"]

This selects <span>s having an attribute like data-technologies="javascript" but also data-technologies="jquery javascript qunit". You can think of it as the equivalent of the Class selector but for a generic attribute.

The presented selectors can also be chained in case you need to retrieve nodes that match more criteria. You can chain as many selectors as you like; there isn’t a fixed limit. For example, you can write

input[type="text"][required]

This selector retrieves all the <input>s that are required (the required attribute has been introduced in HTML5) and are of type text.

Table 2.3 summarizes the CSS selectors that deal with attributes that you can use in jQuery.

Table 2.3. The attribute selectors supported by jQuery
SelectorDescriptionIn CSS?
E[A]Matches all elements with tag name E that have attribute A of any value
E[A=’V’]Matches all elements with tag name E that have attribute A whose value is exactly V
E[A^=’V’]Matches all elements with tag name E that have attribute A whose value starts with V
E[A$=’V’]Matches all elements with tag name E that have attribute A whose value ends with V
E[A!=’V’]Matches all elements with tag name E that have attribute A whose value doesn’t match V (are not equal to V) or that lack attribute A completely
E[A*=’V’]Matches all elements with tag name E that have attribute A whose value contains V
E[A|=’V’]Matches all elements with tag name E that have attribute A whose value is equal to V or to V- (V followed by a hyphen)
E[A~=’V’]Matches all elements with tag name E that have attribute A whose value is equal to V or contains V delimited by spaces
E[C1][C2]Matches all elements with tag name E that have attributes that satisfy the criteria C1 and C2

With all this knowledge in hand, head over to the jQuery Selectors Lab Page and spend some more time running experiments using selectors of various types from table 2.3. Try to make some targeted selections like the input element having the type of checkbox and the value of 1 (hint: you’ll need to use a combination of selectors to get the job done).

Selectors aren’t used only to retrieve elements using the $() function. As you’ll discover later in this lesson, they’re one of the most used parameters to pass to jQuery’s methods. For example, once you’ve made a selection, you can use a jQuery method and a new selector to add new elements to the previous set or to filter some elements. Another case is to find all the descendants of the elements in a previous stored set that match a given selector.

As if the power of the selectors that we’ve discussed so far isn’t enough, there are some more options that offer an even finer ability to slice and dice the DOM. In the next section we’ll introduce other types of selectors known as filters. In the CSS specification these types of selectors are referred as pseudo-classes.


Posted

in

by

Tags:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *