dojo.query¶
dojo.query() returns a list of DOM nodes based on a CSS selector.
Introduction¶
XHR is half of the AJAX story. Once you make a request for data and receive it via dojo.xhr, you must change the page - display the new data in a panel, turn an indicator from red to green, or whatever. Changing HTML is, in turn, dependent on locating nodes.
A bad solution: using the DOM API¶
To select HTML elements in JavaScript, you can use the browser’s native DOM API, but they’re verbose and hard to work with...not to mention slow. For example, retrieving all nodes with the class “progressIndicator” uses this code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <script type="text/javascript">
// list every node with the class "progressIndicator":
var list = [];
var nodes = document.getElementsByTagName("*");
// iterate over every node in the document....SLOOOW
for(var x = 0; x < nodes.length; x++){
// only nodes with the class "progressIndicator":
if(nodes[x].className == "progressIndicator"){
// add to array:
list.push(nodes[x]);
}
}
console.dir(list);
</script>
|
Oy! That's a lot of code for what should be very simple. It's also very slow.
Better and faster: dojo.query¶
dojo.query gives us a more compact way to do it, and it's often faster, particularly as we ask for more sophisticated kinds of relationships. The following is exactly equivalent to our first example:
1 2 3 4 | <script type="text/javascript">
// list every node with the class "progressIndicator":
console.dir( dojo.query(".progressIndicator") );
</script>
|
Usage¶
Users of other libraries will find the syntax very familiar:
dojo.addOnLoad(function(){
// every element in the page with the class "blueButton" assigned
dojo.query(".blueButton").forEach(function(node, index, arr){
console.debug(node.innerHTML);
});
});
The returned object of a dojo.query() call is an instance of dojo.NodeList, a subclass of Array with many convenience methods added for making DOM manipulation and event handling easier. Custom extensions of the dojo.NodeList class are supported and encouraged.
Examples¶
Simple Queries¶
// all <h3> elements
dojo.query('h3')
// all <h3> elements which are first-child of their parent node
dojo.query('h3:first-child')
// a node with id="main"
dojo.query('#main')
// all <h3> elements within a node with id="main"
dojo.query('#main h3')
// a <div> with an id="main"
dojo.query('div#main')
// all <h3> elements within a div with id="main"
dojo.query('div#main h3')
// all <h3> elements that are immediate children of a <div>, within node with id="main"
dojo.query('#main div > h3')
// all nodes with class="foo"
dojo.query('.foo')
// all nodes with classes "foo" and "bar"
dojo.query('.foo.bar')
// all <h3> elements that are immediate children of a node with id="main"
dojo.query('#main > h3')
Immediate Child Elements¶
dojo.query('#main > *')
dojo.query('#main >')
dojo.query('.foo >')
dojo.query('.foo > *')
Queries rooted at a given element¶
dojo.query('> *', dojo.byId('container'))
dojo.query('> h3', 'main')
Multiple class attribute values¶
dojo.query('.foo.bar')
Using attribute selectors¶
Picking out elements with particular attributes/values
dojo.query('[foo]')
dojo.query('[foo$=\"thud\"]')
dojo.query('[foo$=thud]')
dojo.query('[foo$=\"thudish\"]')
dojo.query('#main [foo$=thud]')
dojo.query('#main [ title $= thud ]')
dojo.query('#main span[ title $= thud ]')
dojo.query('[foo|=\"bar\"]')
dojo.query('[foo|=\"bar-baz\"]')
dojo.query('[foo|=\"baz\"]')
dojo.query('.foo:nth-child(2)')
Descendant selectors¶
dojo.query('>', 'container')
dojo.query('> *', 'container')
dojo.query('> [qux]', 'container')
Sibling selectors¶
dojo.query('.foo + span')
dojo.query('.foo ~ span')
dojo.query('#foo ~ *')
dojo.query('#foo ~')
Sub-selectors, using not()¶
dojo.query('#main span.foo:not(span:first-child)')
dojo.query('#main span.foo:not(:first-child)')
Nth-child¶
dojo.query('#main > h3:nth-child(odd)')
dojo.query('#main h3:nth-child(odd)')
dojo.query('#main h3:nth-child(2n+1)')
dojo.query('#main h3:nth-child(even)')
dojo.query('#main h3:nth-child(2n)')
dojo.query('#main h3:nth-child(2n+3)')
dojo.query('#main > *:nth-child(2n-5)')
Using pseudo-selectors¶
dojo.query('#main2 > :checked')
dojo.query('#main2 > input[type=checkbox]:checked')
dojo.query('#main2 > input[type=radio]:checked')
Count of checked checkboxes in a form with id myForm¶
dojo.query('input:checked', 'myForm').length
Standard CSS3 Selectors¶
Because dojo.query adopts the CSS3 standard for selecting nodes, you can use any CSS reference guide for help on choosing the right queries. Eric Meyer's CSS: The Definitive Guide is a good resource. For convenience, here's a chart of the standard CSS3 selectors, taken from the current working draft RFC.
Pattern | Meaning |
---|---|
* | any element |
E | an element of type E |
E[foo] | an E element with a "foo" attribute |
E[foo="bar"] | an E element whose "foo" attribute value is exactly equal to "bar" |
E[foo~="bar"] | an E element whose "foo" attribute value is a list of space-separated values, one of which is exactly equal to "bar" |
E[foo^="bar"] | an E element whose "foo" attribute value begins exactly with the string "bar" |
E[foo$="bar"] | an E element whose "foo" attribute value ends exactly with the string "bar" |
E[foo*="bar"] | an E element whose "foo" attribute value contains the substring "bar" |
E[hreflang|="en"] | an E element whose "hreflang" attribute has a hyphen-separated list of values beginning (from the left) with "en" |
E:root | an E element, root of the document |
E:nth-child(n) | an E element, the n-th child of its parent |
E:nth-last-child(n) | an E element, the n-th child of its parent, counting from the last one |
E:nth-of-type(n) | an E element, the n-th sibling of its type |
E:nth-last-of-type(n) | an E element, the n-th sibling of its type, counting from the last one |
E:first-child | an E element, first child of its parent |
E:last-child | an E element, last child of its parent |
E:first-of-type | an E element, first sibling of its type |
E:last-of-type | an E element, last sibling of its type |
E:only-child | an E element, only child of its parent |
E:only-of-type | an E element, only sibling of its type |
E:empty | an E element that has no children (including text nodes) |
E:link | |
E:visited | an E element being the source anchor of a hyperlink of which the target is not yet visited (:link) or already visited (:visited) |
E:active | |
E:hover | |
E:focus | an E element during certain user actions |
E:target | an E element being the target of the referring URI |
E:lang(fr) | an element of type E in language "fr" (the document language specifies how language is determined) |
E:enabled | |
E:disabled | a user interface element E which is enabled or disabled |
E:checked | a user interface element E which is checked (for instance a radio-button or checkbox) |
E::first-line | the first formatted line of an E element |
E::first-letter | the first formatted letter of an E element |
E::selection | the portion of an E element that is currently selected/highlighted by the user |
E::before | generated content before an E element |
E::after | generated content after an E element |
E.warning | an E element whose class is "warning" (the document language specifies how class is determined). |
E#myid | an E element with ID equal to "myid". |
E:not(s) | an E element that does not match simple selector s |
E F | an F element descendant of an E element |
E > F | an F element child of an E element |
E + F | an F element immediately preceded by an E element |
E ~ F | an F element preceded by an E element |
Table of Contents
- dojo.query
- Introduction
- Usage
- Examples
- Simple Queries
- Immediate Child Elements
- Queries rooted at a given element
- Compound queries
- Multiple class attribute values
- Using attribute selectors
- Descendant selectors
- Sibling selectors
- Sub-selectors, using not()
- Nth-child
- Using pseudo-selectors
- Count of checked checkboxes in a form with id myForm
- Standard CSS3 Selectors