Traversing the DOM

An access always starts from the document.

This object provides a variety of methods to search and modify elements.

The root: documentElement and body

The root is the DOM always document.documentElement. This special property will give access to the topmost HTML tag.

Another starting point can be the document.body, which represents the BODY tag.

documentElement

Both entry points are valid. But document.body can be null.

For example, you access document.body from an inline script in the HEAD, prepare to see null instead. That’s natural, because there is no BODY yet.

In the example below, first alert outputs null:

 

01 <!DOCTYPE HTML>
02 <html>
03     <head>
04         <script>
05             alert("Body from HEAD: "+document.body) // null
06         </script>
07     </head>
08     <body>
09         <div>The document</div>
10
11         <script>
12             // different browsers output different text here,
13             // because of different implementations of toString
14
15             alert("Body from inside body: " + document.body)
16         </script>
17     </body>
18 </html>

Open the code in new window

Contrary to this, document.documentElement is available always.

Also note that document.body can’t be undefinedIn the world of DOM, an “element not found” or “no such element” is always null.

 

As a more general rule than described above, it is impossible to reference elements that are not yet rendered at the time of script execution.

 

  • Write the code to access the UL using children.
  • Write the code to access the second LI using children.
Solution

The code is cross-browser:

document.body.children[1]
document.body.children[1].children[1]

It works fine, because there are no comment nodes before UL, so children indexes are same for IE<9 and other browsers.

 

Getting a list of children is not enough for convenient walking around elements.
So, there are additional properties for siblings, parent, etc.

The firstChild and the lastChild

The firstChild and lastChild properties allow to quickly access first or last child.

children

They are basically same as corresponding childNodes indexes:

1 var body = document.body
2
3 alert(body.firstChild === body.childNodes[0])
4 alert(body.lastChild === body.childNodes[body.childNodes.length-1])

 

parentNodepreviousSibling and nextSibling

  • The parentNode property references the parent node. It equals null fordocument.documentElement.
  • The previousSibling and nextSibling allow to access the left or the right neightbour.

For example:

01 <!DOCTYPE HTML>
02 <html>
03 <head>
04    <title>My page</title>
05 </head>
06 <body>
07     <div>The header</div>
08
09     <ul><li>A list</li></ul>
10
11     <div>The footer</div>
12 </body>
13
14 </body>
15 </html>

Picture for the document above (without whitespace nodes):

 

siblings

The browser always maintains correct helper links. It is possible to modify the DOM, add/remove elements, but no need to reassign the links manually, browser does that.

 

Write the code to check if the DOM Node elem is totally empty. That is, there are no children or text in it.

 

if (/*... put here your code to check if the elem is empty... */)

 

Open solution

Is it right that document.body.lastChild.nextSibling is always null?

.. Same question about document.body.children[0].previousSibling ?

Open solution

 

Summary

The DOM tree is tightly interlinked:

up
parentNode
down
children/childNodesfirstChildlastChild
left/right
previousSibling/nextSibling

Browser guarantees that the links are always correct. All of them are read-only.

If there is no such element (child, parent, neighbour etc), the value is null.

Comments are closed.