What is the JavaScript NodeIterator API?
By: Gravity Well, Rob Tomlin
Tags: JavaScript, Programming, Coding, Web Development, Tech

The NodeIterator API

The NodeIterator object is created using the createNodeIterator() method of the document interface.

The syntax is,

const nodeIterator = document.createNodeIterator(root, whatToShow, filter);

As shown, this method takes three arguments.

The root node that holds all the nodes we want to filter for.

The second argument, whatToShow, is a built - in filter that uses constants of the NodeFilter object.

built in filter that uses constants of the object. The third argument, filter, is a function which returns a NodeFilter object used to select the relevant nodes. Here you can specify custom criteria to help decide to either ACCEPT, REJECT or SKIP the node.

The second argument above referred to constants. These are constants of the NodeFilter object and have the form NodeFilter.CONSTANT. The constants might look like,

NodeFilter.SHOW_TEXT (shows text nodes)

NodeFilter.SHOW_ELEMENT (shows element nodes)

When using these, non-matching nodes are skipped, the first level of filtering. A complete list of constants can be found here.

Since NodeIterator is an iterator it supplies us with a method to loop over the nodes, NodeIterator.nextNode().

In plain terms, we specify a starting point in the DOM, traverse the DOM looking for nodes that match our built-in filter and custom filter criteria.

Example — Showing the Elements

Create the following index.html

<!DOCTYPE html>

<html lang="en"> <head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>Document.createNodeIterator</title>

</head> <body>

<div id='main'>

<h1>Traversing The DOM</h1> <div>

First Name:<input type='text'><br/>

Last Name:<input type='text'><br/>

</div>

<br/>

<div>

To Do:

<ul>

<li>Wash Clothes</li>

<li>Do Dishes</li>

<li>Write Code</li>

</ul>

</div> </div>

<script src="index.js"> </script> </body>

</html>

Next create the following index.js

window.onload = ()=> {

// The starting node

getNodesStartingAt(document.querySelector('#main'));

} function getNodesStartingAt(myRoot) { const nodeIterator = document.createNodeIterator(

myRoot,

NodeFilter.SHOW_ELEMENT,

(node) => {

// ACCEPT, REJECT OR SKIP based on

// custom criteria

return NodeFilter.FILTER_ACCEPT;

}

); let currentnode; while (currentnode = nodeIterator.nextNode()) {

console.log(currentnode.tagName);

}

}

Test Run

Open index.html.

Open your browser’s console window and observe the output.

Output for NodeFilter.SHOW_ELEMENT

Try changing the starting root by modifying the function call as follows,

getNodesStartingAt(document.body);

Try changing the output of console.log() by changing the loop as follows,

while (currentnode = nodeIterator.nextNode()) {

console.log(currentnode.innerHTML);

}

Try changing the NodeFilter.CONSTANT to NodeFilter.SHOW_TEXT and console.log() output to the nodeValue. See Bold items below.

window.onload = ()=> {

// The starting node

getNodesStartingAt(document.body);

} function getNodesStartingAt(myRoot) { const nodeIterator = document.createNodeIterator(

myRoot,

NodeFilter.SHOW_TEXT,

(node) => {

// ACCEPT, REJECT OR SKIP based on

// custom criteria

return NodeFilter.FILTER_ACCEPT;

}

); let currentnode; while (currentnode = nodeIterator.nextNode()) {

console.log(currentnode.nodeValue);

}

}

This produces,

Output for NodeFilter.SHOW_TEXT

We will work with the TreeWalker in another article, but here is a quick look.

The TreeWalker API

The main difference between these two interfaces is that the TreeWalker presents a tree-oriented view of the nodes in a subtree, rather than the iterator’s list-oriented view.

TreeWalker also has a few additional methods.

previousNode -(also in NodeIterator.) Travels to and returns the previous node of the current node.

-(also in NodeIterator.) Travels to and returns the previous node of the current node. nextNode -(also in NodeIterator.) Travels to and returns the next node within the filtered collection of nodes.

-(also in NodeIterator.) Travels to and returns the next node within the filtered collection of nodes. parentNode - Travels to and returns the current node’s parent node.

- Travels to and returns the current node’s parent node. firstChild - Travels to and returns the first child of the current node.

- Travels to and returns the first child of the current node. lastChild - Travels to and returns the first child of the current node.

- Travels to and returns the first child of the current node. previousSibling - Travels to and returns the previous sibling of the current node.

- Travels to and returns the previous sibling of the current node. nextSibling- Travels to and returns the next sibling of the current node.

TreeWalker has four arguments. The first three are the same as NodeIterator. The syntax is,

document.createTreeWalker(root, whatToShow, filter, entityExpandBol)

The last argument is a boolean parameter specifying whether entity references should be expanded.

Example

Use the same index.html but change index.js as follows.

window.onload = ()=> {

// The starting node

getNodesStartingAt(document.querySelector('#main'));

} function getNodesStartingAt(myRoot) { const treeWalker = document.createTreeWalker(

myRoot,

NodeFilter.SHOW_ELEMENT,

(node) => {

// ACCEPT, REJECT OR SKIP based on

// custom criteria

return NodeFilter.FILTER_ACCEPT;

}

); let currentnode;

while (currentnode = treeWalker.nextNode()) {

console.log(currentnode.tagName);

}



Conclusion:

The ability to locate all or part of the DOM tree can be quite useful for low-level examination and potential manipulation of the DOM. In a simplistic way, that is what is being done in modern applications all the time, SPA’s for example.

Much of the power will come in the third argument, the custom filter. It is in here that we can ACCEPT, REJECT or SKIP based on whatever criteria we choose.

I encourage you to experiment with the constants filter (second argument), custom filter (third argument) and with a more complicated HTML document.

Thank you for reading and happy coding!