W3C CSS Selectors API- The querySelector()
and querySelectorAll()
methods
Last updated: June 4th, 2014
The querySelector()
and querySelectorAll()
methods let you enter a CSS selector as a parameter and return the selected
elements as DOM elements. Part of the
W3C Selectors
API, the difference between the two methods is merely in the
number of possible elements that they return- the very first matched
element versus the entire set. Apart from being far more versatile than the
staple getElementById()
and getElementsByTagName()
methods, these two methods also benefit from some incredible lookup speed, as they
take advantage of the same engine the browser uses to identify elements to
style when
parsing the CSS of a page.
Ok, time for the obligatory reality check here- in terms of browser
support, querySelector()
and querySelectorAll()
is supported in Firefox 3.1+, IE8+
(only in IE8 standards mode), and
Safari 3.1+.
The querySelector()
method
The querySelector()
method exists both on as a
Document and as an
Element object. This lets you query either the entire document tree,
or just a specific chunk of it looking for that elusive element of
yours. It accepts any CSS selector as its parameter (ie: "#mydiv img
")
and returns either the first matched element (if multiple exists), or
null
if none. For example:
document.querySelector('#myheader') //returns the element with ID="myheader"
document.querySelector('p.description') //returns the P with
class="description" element
document.querySelector('#content img:nth-of-type(1)') //returns the 1st
image within container "#content"
document.querySelector('#myform input[type="radio"]:checked') //selects the
checked radio button within "#myform"
document.querySelector('form[action="feedback.php"]') // references form
with action="feedback.php"
document.querySelector('img[src^="http"]') // selects 1st image with src
beginning with "http"
document.querySelector('img[src$="blank.gif"]') // selects 1st image with
src ending in "blank.gif"
document.querySelector('#biography, #gallery') //returns either element "#biography" or "#gallery", depending on which one is found first within document tree
Take a look at the last example above- you can enter
multiple CSS selectors, each seperated by a comma (","). The comma acts like
the logical OR
statement here, which causes
querySelector()
to return the first element within the document tree
that matches one of the CSS selectors entered.
Ok, time for a quick demonstration. The below HTML creates a nested DIV, with the inner DIV changing background color whenever the mouse rolls over the outer DIV itself. It makes use of querySelector() both as a document method, and element method:
<div id="outerdiv"
style="padding:50px; width:100px; height:100px; border:1px solid black">
<div id="innerdiv" style="width:100%; height:100%; border:1px solid black;
background:silver;">
</div>
</div>
<script type="text/javascript">
if (document.querySelector){
var outerdiv=document.querySelector('#outerdiv')
outerdiv.onmouseover=function(){
this.querySelector('#innerdiv').style.background="yellow"
}
outerdiv.onmouseout=function(){
this.querySelector('#innerdiv').style.background="silver"
}
}
</script>
Demo (requires FF 3.1+, Safari 3.1+, or IE8+):
The querySelectorAll()
method
The querySelectorAll()
method behaves just like its more
humble cousin above with the exception it returns not just a singular
element that matches a CSS selector, but all of them as a
staticNodeList
. A staticNodeList
is a static
collection of elements that are not affected by any subsequent changes
occurring on the document tree, such as the removal of one those
elements. It supports a "length
" property for you to step
through each of the elements similar to in an Array. With that said:
document.querySelectorAll('.mygroup') //returns all elements with class="mygroup"
document.querySelectorAll('option[selected="selected"]') //returns the
default selected option within each SELECT menu
document.querySelectorAll('#mytable tr>td:nth-of-type(1)') //returns the
first cell within each table row of "mytable"
document.querySelectorAll('a[src^="http"]') // selects all links with href
beginning with "http"
document.querySelectorAll('a[href*="javascriptkit"]') // selects all links
with href containing sub string 'javascriptkit'
document.querySelectorAll('#biography, #gallery') //returns both elements "#biography" and "#gallery" (inclusive)
Ok, demo time! Lets use querySelectorAll()
to quickly
identify all checkboxes that are selected within a particular form:
<form id="myform">
<b>Your hobbies:</b><input name="hobbies" type="checkbox" value="movies"
/>Movies <input name="hobbies" type="checkbox" value="sports" />Sports
<input name="hobbies" type="checkbox" value="reading" />Reading <input
name="hobbies" type="checkbox" value="sleeping" />Sleeping
<br />
<input type="submit" />
</form>
<script type="text/javascript">
if (document.querySelector){
document.querySelector('#myform').onsubmit=function(){
var checkedhobbies=this.querySelectorAll('input[name="hobbies"]:checked')
for (var i=0; i<checkedhobbies.length; i++){
alert(checkedhobbies[i].value)
}
return false
}
}
</script>
Demo (requires FF 3.1+, Safari 3.1+, or IE8+):
Finally, if some of the CSS selectors used above confuse you, you'll want to read up on "Overview of CSS3 Structural pseudo-classes".
IE8 restrictions
In IE8, there are several restrictions you should be aware of when using
querySelector()
and querySelectorAll()
. They
are:
- Your document must be in IE8 standards mode in order for these two
methods to work. A document becomes non standard when it contains a non
strict doctype, or explicitly set to be in IE7 standards mode instead
using the meta tag:
<meta http-equiv="X-UA-Compatible" content="IE=7" />
. For more info on IE8's "exciting" new rendering modes, see this document. - IE8 does not support an optional 2nd "
NSResolver
" parameter passed into eitherquerySelector()
andquerySelectorAll()
to resolve namespace prefixes in XHTML documents, as defined by the W3C. - For security reasons, IE8 will not return elements specified using
the CSS Selectors "
:visited"
or ":link
". This is to prevent webmasters from detecting the links on the page the user has visited.
A less versatile but simpler alternative- getElementsByClassName()
There's another new DOM method vying for your attention when it comes to
easily gathering up elements on the page, and that's
getElementsByClassName()
. As its name suggests, this method
returns a collection of element(s) based on their shared class name, for
example:
//get elements with "cats" class name
document.getElementsByClassName("cats")
//get elements with "cats" or "dogs" class names (inclusive)
document.getElementsByClassName("cats dogs")
You can use this method in place of the Query Selector methods when all
you want is to get elements on the page identified by a common CSS class. As
a native method of the browser, it's also blazingly fast. In terms of
browser support,
getElementsByClassName()
is recognized in FF3+, Opera 9.5+ and
Safari 3+. Sadly, IE8 is not yet part of that list, which it is for the
Query Selector methods.