Page 1 of 2
Selectors are what jQuery uses to pick out particular objects in the DOM. While this might start out simply enough, it can appear to be complicated in more testing examples. The trick is to always remember what the selector is doing.
In the previous article we introduced the idea that one of the big uses of jQuery is in finding sets of DOM objects so that we can work with them.
There are two phases to learning the core of jQuery. The first is learning how to pick out the elements that you want. The second is finding out how to make the changes that you require.
In this article we focus on finding elements, leaving manipulation to another article. Of course, jQuery isn't of much use if all you can do is find elements but it is the first, and necessary step.
In an ideal world any element, or its corresponding DOM object, would be easy to find because it would have a unique id. Even sets of DOM objects that share a set of common properties should be easy to find because they should all belong to the same class.
Before going any deeper, it is worth saying that the three most used jQuery selectors are
- name all tags like <name>
- #name the singe tag with id="name"
- .name all tags with class="name"
So for example $('div') selects all the DOM objects that correspond to div elements; $('#mydiv'") selects the one element with id set to mydiv; $(".bigdiv") selects all elements with class set to bigdiv.
For many jQuery users these are the only selectors needed but if these are the only selectors you know the more general and powerful patterns you can use will not be obvious to you.
In an ideal world you would be able to find every element you needed using just these three selectors but when you have to work with web pages generated by CMS or templates then often you have to work with what you are given. In other words it is sometimes not possible to modify the HTML so that the elements you want to select all have ids or belong to a single class.
It is worth remembering that jQuery always returns an array of elements that match the selector even if there is only one match.
It is also worth remembering that many jQuery methods operate on the first element of the array - which makes working with a single element much easier - or on all of the elements..
Once you graduate beyond the three basic selectors you need to have a framework to organize things - without a framework everything looks like a special case.
The first thing to say is that the fundamental selector is the type selector i.e name which selects all elements corresponding to <name>. All other selectors take the form of extra conditions on this basic selector.
selects elements corresponding to all <p> tags. All other selectors are modifications and extensions on this basic selector.
There is also a universal type selector - the asterisk * which matches every element type. This may not seem to be very useful at first, but it is often used within a larger selector to mean any element type that satisfies other conditions. This will become clear in a moment.
The basic type selector can be modified with additional conditions - usually indicated by a colon or a square brackets or another special symbol. For example if you want to specify a type with a particular id you can write
to select all <p> elements with id equal to name. Of course there can only be one element with id equal to name so you don't really need to specify the type. This can be done using the universal type selector i.e.
selects any type of element with id equal to name. The convention is that if you don't specify a type then the universal type selector is assumed. This means that you can simply write
and now you can see that the id selector is just a special case of the more general type selector.
In the same way the .class selector is a short hand for
which selects all elements with the class attribute equal to name. In general the class selector is:
which selects all elements of type T with class set to name.
Combining Type Selectors
Now that we know that the basic selector is the type selector it is time to discover how these can be used together.
If you have two type selectors T1 and T2 then just writing them one after the other
means all T2s nested within T1s.
selects all <p> elements that are contained within a <div>. Notice that it doesn't matter how deeply nested the <p> is within other elements. If there is a containing <div> then the <p> is selected.
You can use as many types as you like to define complicated nestings of elements. For example:
$("div div p")
selects <p> elements that are nested within two divs. Notice that this means at least two divs - it doesn't select <p> elements nested within one div but it does select <p> elements nested withing two, three or more <divs>.
You can use the universal selector to define nesting relationships that are independent of type. For example
$("div * p")
means <p> elements nested within any other element and an outer containing div.
If you simply write type selectors separated by spaces then you are defining nesting relationships. You can use two other separators to indicate other types of relationship.
T1 > T2
means T2 has to be a child of T1 i.e. T2 has to be directly contained within T1.
So for example
$("div > p")
selects all <p> elements that are immediately contained within a div. Compare this to
which means that the p has to be contained with in the div but there can be other types between it and the div.
Finally we have
T1 + T2
which means that T2 is selected if T2 immediately follows T1, ignoring non-elements such as text and comments. In this context "immediately following" means that T2 isn't nested in T1.
$("h1 + div")
selects all divs that immediately follow an h1.
The final way to combine type selectors is very simple. You can making a list of selectors separated by commas to mean elements that match any of the selectors.
$("h1, div, p")
this selects all h1, div and p elements
Finally it should be fairly obvious that you can mix these types of selectors together. It may be obvious that you can do it but sometimes it can be very difficult to work out what they mean.
$("div * p > span ")
specifies a <span> that is immediately contained by a <p>, contained by any element contained by a <div>.
The trick in understanding more complicated selectors is to realize that you read them from right to left with the conditions being added to reduce the number of elements selected. So starting from the right we have span i.e. pick out elements that correspond to <span>. Next we have p> which adds the condition that the span has to be a child of a <p> , which according to the * has to be a child of some other element and finally the div adds that it has to be contained by a div.
- The most basic selector is a type selector. T selects all <T> elements
- The universal type selector * selects any element
- T1 T2 selects a <T2> contained in a <T1>
- T1>T2 selects a <T2 > that is immediately contained i.e. is a child of, T1
- T1+T2 selects a <T2> that immediately follows a <T1>
- T1,T2,T3... selects elements that are selected by any of T1, T2, T3 ...