Chapter 4 - Element Node Selec

4.1 Selecting a specific element node

The most common methods for getting a reference to a single element node are:

  • querySelector()
  • getElementById()

In the code below I leverage both of these methods to select an element node from the HTML document.

live code: http://jsfiddle.net/domenlightenment/b4Rch

<!DOCTYPE html>
<html lang="en">
<body>

<ul>
<li>Hello</li>
<li>big</li>
<li>bad</li>
<li id="last">world</li>
</ul>

<script>

console.log(document.querySelector("li").textContent); //logs Hello
console.log(document.getElementById("last").textContent); //logs world

</script>
</body>
</html>

The getElementById() method is pretty simple compared to the more robust querySelector() method. ThequerySelector() method permits a parameter in the form of a CSS selector syntax. Basically you can pass this method a CSS 3 selector (e.g. "#score>tbody>tr>td:nth-of-type(2)") which it will use to select a single element in the DOM.

Notes

querySelector() will return the first node element found in the document based on the selector. For example, in the code example above we pass a selector that would select all the li"s in CSS, but only the first one is returned.

querySelector() is also defined on element nodes. This allows for the method to limit (allows for context querying) its results to a specific vein of the DOM tree

4.2 Selecting/creating a list (aka NodeList) of element nodes

The most common methods for selecting/creating a list of nodes in an HTML document are:

  • querySelectorAll()
  • getElementsByTagName()
  • getElementsByClassName()

Below we use all three of these methods to create a list of the <li> elements in the document.

live code: http://jsfiddle.net/domenlightenment/nT7Lr

<!DOCTYPE html>
<html lang="en">
<body>

<ul>
<li class="liClass">Hello</li>
<li class="liClass">big</li>
<li class="liClass">bad</li>
<li class="liClass">world</li>
</ul>

<script>

//all of the methods below create/select the same list of <li> elements from the DOM
console.log(document.querySelectorAll("li"));
console.log(document.getElementsByTagName("li"));
console.log(document.getElementsByClassName("liClass"));

</script>
</body>
</html>

If its not clear the methods used in the code example above do not select a specific element, but instead creates a list (aka NodeLists) of elements that you can select from.

Notes

NodeLists created from getElementsByTagName() and getElementsByClassName() are considered live are will always reflect the state of the document even if the document is updated after the list is created/selected.

The querySelectorAll() method does not return a live list of elements. Meaning that the list created fromquerySelectorAll() is a snap shot of the document at the time it was created and is not reflective of the document as it changes. The list is static not live.

querySelectorAll()getElementsByTagName(), and getElementsByClassName are also defined on element nodes. This allows for the method to limit its results to specific vein(s) of the DOM tree (e.g.document.getElementById("header").getElementsByClassName("a")).

I did not mention the getElementsByName() method as it not commonly leverage over other solutions but you should be aware of its existence for selecting form, img, frame, embed, and object elements from a document that all have the same name attribute value.

Passing either querySelectorAll() or getElementsByTagName() the string ""*, which generally means all, will return a list of all elements in the document.

Keep in mind that childNodes will also return a NodeList just like querySelectorAll()getElementsByTagName(), andgetElementsByClassName

The NodeLists are array like (but does not inherit array methods) lists/collections and have a read only length property

4.3 Selecting all immediate child element nodes

Using the children property from an element node we can get a list (aka HTMLCollection) of all the immediate children nodes that are element nodes. In the code below I use children to create a selection/list of all of the<li>"s contained wiithin the <ul>.

live code: http://jsfiddle.net/domenlightenment/svfRC

<!DOCTYPE html>
<html lang="en">
<body>

<ul>
<li><strong>Hi</strong></li>
<li>there</li>
</ul>

<script>

var ulElement = document.querySelector("ul").children;

//logs a list/array of all immediate child element nodes
console.log(ulElement); //logs [<li>, <li>]

</script>
</body>
</html>

Notice that using children only gives us the immediate element nodes excluding any nodes (e.g. text nodes) that are not elements. If the element has no children then children will return an empty array-like-list.

Notes

HTMLCollection"s contain elements in document order, that is they are placed in the array in the order the elements appear in the DOM

HTMLCollection"s are live, which means any change to the document will be reflected dynamically in the collection

4.4 Contextual element selecting

The methods querySelector()querySelectorAll()getElementsByTagName(), andgetElementsByClassName typically accessed from the document object are also defined on element nodes. This allows for these methods to limit its results to specific vein(s) of the DOM tree. Or said another, you can select a specific context in which you would like the methods to search for element nodes by invoking these methods on element node objects.

live code: http://jsfiddle.net/domenlightenment/fL6tV

<!DOCTYPE html>
<html lang="en">
<body>

<div><ul><li class="liClass">Hello</li><li class="liClass">big</li><li class="liClass">bad</li><li class="liClass">world</li></ul></div>

<ul><li class="liClass">Hello</li></ul>

<script>

//select a div as the context to run the selecting methods only on the contents of the div
var div = document.querySelector("div");

console.log(div.querySelector("ul"));
console.log(div.querySelectorAll("li"));
console.log(div.getElementsByTagName("li"));
console.log(div.getElementsByClassName("liClass"));

</script>
</body>
</html>

These methods not only operate on the live dom but programatic DOM structures that are created in code as well.

live code: http://jsfiddle.net/domenlightenment/CCnva

<!DOCTYPE html>
<html lang="en">
<body>

<script>

//create DOM structure
var divElm = document.createElement("div");
var ulElm = document.createElement("ul");
var liElm = document.createElement("li");
liElm.setAttribute("class","liClass");
ulElm.appendChild(liElm);
divElm.appendChild(ulElm);

//use selecting methods on DOM structure
console.log(divElm.querySelector("ul"));
console.log(divElm.querySelectorAll("li"));
console.log(divElm.getElementsByTagName("li"));
console.log(divElm.getElementsByClassName("liClass"));

</body>
</html>

4.5 Pre-configured selections/lists of element nodes

You should be aware that there are some legacy, pre-configured arrays-like-lists, containing element nodes from an HTML document. Below I list a couple of these (not the complete list) that might be handy to be aware of.

  • document.all - all elements in HTML document
  • document.forms - all <form> elements in HTML document
  • document.images - all <img> elements in HTML document
  • document.links - all <a> elements in HTML document
  • document.scripts - all <script> elements in HTML document
  • document.styleSheets - all <link> or <style> objects in HTML document

Notes

These pre-configured arrays are constucted from the HTMLCollection interface/object, except document.styleSheets it usesStyleSheetList

HTMLCollection"s are live just like NodeList"s.

Oddly document.all is constucted from a HTMLAllCollection not an HTMLCollection and is not supported in Firefox

4.6 Verify an element will be selected using matchesSelector()

Using the matchesSelector() method we can determine if an element will match a selector string. For example say we want to determine if an <li> is the first child element of a <ul>. In the code example below I select the first<li> inside of the  <ul>and then ask if that element matches the selector, li:first-child. Because it in fact does, the matchesSelector() method returns true.

live code: http://jsfiddle.net/domenlightenment/9RayM

<!DOCTYPE html>
<html lang="en">
<body>

<ul>
<li>Hello</li>
<li>world</li>
</ul>

<script>

//fails in modern browser must use browser prefix moz, webkit, o, and ms
console.log(document.querySelector("li").matchesSelector("li:first-child")); //logs false

//prefix moz
//console.log(document.querySelector("li").mozMatchesSelector("li:first-child"));

//prefix webkit
//console.log(document.querySelector("li").webkitMatchesSelector("li:first-child"));

//prefix o
//console.log(document.querySelector("li").oMatchesSelector("li:first-child"));

//prefix ms
//console.log(document.querySelector("li").msMatchesSelector("li:first-child"));

</script>
</body>
</html>

Notes

matchesSelector has not seen much love from the browsers as its usage is behind browser prefixes mozMatchesSelector(),webkitMatchesSelector()oMatchesSelector()msMatchesSelector()

In the future matchesSelector() will be renamed to matches()

文章导航