DOM Traversal - Java Script

Up until this point,the features discussed have all been part of DOM Level 1.This section introduces some of the features of DOM Level 2,specifically objects in the DOM Level 2 Traversal and Range specification relating to traversing a DOM document.These features are only available in Mozilla and Konqueror/Safari.

NodeIterator

The first object of interest is the NodeIterator, which enables you to do a depth-first search of a DOM tree,which can be useful if you are looking for specific types of information(or elements) in a page. To understand what the NodeIterator does,consider the following HTML page:

This page evaluates to the DOM tree represented .

page evaluates to the DOM tree represented

When using a NodeIterator, it’s possible to start from the document element, <html/>,and traverse the entire DOM tree in a systematic way known as a depth-first search.In this method of searching, the traversal goes as deep as it possibly can from parent to child,to that child’s child, and so on, until it can’t go any further. Then, the traversal goes back up one level and goes to the next child. For instance,in the DOM tree shown previously, the traversal first visits <html/>,then <head/>, then <title/>,then the text node “Example”, before going back up to <body/>.displays the complete path for the traversal.

The best way to think of a depth-first search is to draw a line that starts from the left of the first node and follows the outline of the tree. Whenever the line passes a node on its left,the node appears next in the search (this line is indicated by the thick line in )

page evaluates to the DOM tree represented

To create a NodeIterator object,use the createNodeIterator() method of the document object.Thismethod accepts four arguments:

  1. root — the node in the tree that you wish to start searching from
  2. whatToShow — a numerical code indicating which nodes should be visited
  3. filter — a NodeFilter object to determine which nodes to ignore
  4. entityReferenceExpansion — a Boolean value indicating whether entity references should be expanded

The whatToShow argument determines which nodes to visit by applying one or more of the following constants:

  • NodeFilter.SHOW_ALL — show all node types
  • NodeFilter.SHOW_ELEMENT — show element nodes
  • NodeFilter.SHOW_ATTRIBUTE — show attribute nodes
  • NodeFilter.SHOW_TEXT — show text nodes
  • NodeFilter.SHOW_CDATA_SECTION — show CData section nodes
  • NodeFilter.SHOW_ENTITY_REFERENCE — show entity reference nodes
  • NodeFilter.SHOW_ENTITY — show entity nodes
  • NodeFilter.SHOW_PROCESSING_INSTRUCTION — show PI nodes
  • NodeFilter.SHOW_COMMENT — show comment nodes
  • NodeFilter.SHOW_DOCUMENT — show document nodes
  • NodeFilter.SHOW_DOCUMENT_TYPE — show document type nodes
  • NodeFilter.SHOW_DOCUMENT_FRAGMENT — show document fragment nodes
  • NodeFilter.SHOW_NOTATION — show notation nodes

You can combine multiple values by using the bitwise OR operator:

var iWhatToShow = NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT;

The filter argument of createNodeIterator() can be used to specify a custom NodeFilter object, but can also be left null if you don’t want to use it.

To create a simple NodeIterator that visits all node types, use the following:

To move forward and backward in the search,use the nextNode() and previousNode() methods:

For example, suppose you wanted to list all elements contained within a specific <div/> inside of a area on an HTML page.The following code accomplishes this:

When the button is clicked, the <textarea/> is filled with the tag names of the elements contained in

div1:

But suppose you don’t want to include <p/>elements in the results. This can’t be accomplished just byusing the whatToShow argument.In this case, you need a custom NodeFilter object.ANodeFilter object has only one method:

acceptNode(),which returns NodeFilter.FILTER_ACCEPT if the given node should be visited or NodeFilter.FILTER_REJECT if the given node should not be visited.

However,you cannot create an object using the class NodeFilter because it is an abstract class. In Java or other languages, you must define a new subclass of NodeFilter, but because this is JavaScript you can’t do that.

Instead,you just create an object with an acceptNode() method and pass that to the createNodeIterator() method,like this:

To disallow <p/> element nodes, you just check the tagName property and return NodeFilter.

FILTER_REJECT if it’s equal to “P”:


If you include this in the previous example,the code becomes the following:

This time when the button is clicked, the <textarea/> is filled with the following:

Note that both “P” and “B” have disappeared from the list. This is because filtering out the <p/> element eliminates it and all its ancestors from the iteration search.Because <b/> is a child of <p/>,it is also skipped.

The NodeIterator object presents an orderly way of traversing an entire DOM tree(or just part of it) from top to bottom. However, you may want to traverse a particular area of the tree and then look at a node’s sibling or child. In that case, you use a TreeWalker.

TreeWalker

The TreeWalker is like the big brother of NodeIterator: It has all the same functionality (with nextNode() and previousNode()) but with added traversal methods:

  • parentNode()— travels to the current node’s parent
  • firstChild()— travels to the first child of the current node
  • lastChild()— travels to the last child of the current node
  • nextSibling()— travels to the next sibling of the current node
  • previousSibling()— travels to the previous sibling of the current node

To start, you can actually use a TreeWalker just like a NodeIterator by replacing the call to createNodeIterator() with a call to createTreeWalker(), which accepts the same arguments:

Naturally,the true power of a TreeWalker is lost on a simple example such as this;it is much more useful in cases when you don’t want to go straight through the entire DOM tree. For example, suppose you only want to visit the <li/>elements in the HTML page shown previously. You could write a filter that only accepts elements with the tagName “LI”, or you could use a TreeWalker to do a purposive traversal:

In this example, the TreeWalker is created and immediately firstChild() is called, which points thenwalker at the <p/> element (because <p/> is the first child of div1). When nextSibling() is called on the next line, the walker goes to <ul/>, which is the next sibling of <p/>. Then, firstChild() is called to return the first <li/> element under <ul/>.After it is inside the loop, the nextSibling() method is used to iterate through the rest of the <li/> elements.When you click the button, the output is the following:

The bottom line is that the TreeWalker is much more useful when you have an idea about the structure of the DOM tree you will be traversing, whereas a NodeIterator is much more practical when you don’t know the structure.


All rights reserved © 2018 Wisdom IT Services India Pvt. Ltd DMCA.com Protection Status

Java Script Topics