libs:
- d3
- domtree
---
# Walking the DOM
The DOM allows us to do anything with elements and their contents, but first we need to reach the corresponding DOM object.
All operations on the DOM start with the `document` object. That's the main "entry point" to DOM. From it we can access any node.
Here's a picture of links that allow for travel between DOM nodes:

Let's discuss them in more detail.
## On top: documentElement and body
The topmost tree nodes are available directly as `document` properties:
`` = `document.documentElement`
: The topmost document node is `document.documentElement`. That's the DOM node of the `` tag.
`
` = `document.body`
: Another widely used DOM node is the `` element -- `document.body`.
`` = `document.head`
: The `` tag is available as `document.head`.
````warn header="There's a catch: `document.body` can be `null`"
A script cannot access an element that doesn't exist at the moment of running.
In particular, if a script is inside ``, then `document.body` is unavailable, because the browser did not read it yet.
So, in the example below the first `alert` shows `null`:
```html run
```
````
```smart header="In the DOM world `null` means \"doesn't exist\""
In the DOM, the `null` value means "doesn't exist" or "no such node".
```
## Children: childNodes, firstChild, lastChild
There are two terms that we'll use from now on:
- **Child nodes (or children)** -- elements that are direct children. In other words, they are nested exactly in the given one. For instance, `` and `` are children of `` element.
- **Descendants** -- all elements that are nested in the given one, including children, their children and so on.
For instance, here `` has children `` and `
` (and few blank text nodes):
```html run
Begin
```
...And descendants of `` are not only direct children ``, `
` but also more deeply nested elements, such as `- ` (a child of `
`) and `` (a child of `- `) -- the entire subtree.
**The `childNodes` collection lists all child nodes, including text nodes.**
The example below shows children of `document.body`:
```html run
Begin
End
...more stuff...
```
Please note an interesting detail here. If we run the example above, the last element shown is `
````
## Siblings and the parent
*Siblings* are nodes that are children of the same parent.
For instance, here `` and `` are siblings:
```html
......
```
- `` is said to be the "next" or "right" sibling of ``,
- `` is said to be the "previous" or "left" sibling of ``.
The next sibling is in `nextSibling` property, and the previous one - in `previousSibling`.
The parent is available as `parentNode`.
For example:
```js
// parent of is
alert( document.body.parentNode === document.documentElement ); // true
// after goes
alert( document.head.nextSibling ); // HTMLBodyElement
// before goes
alert( document.body.previousSibling ); // HTMLHeadElement
```
## Element-only navigation
Navigation properties listed above refer to *all* nodes. For instance, in `childNodes` we can see both text nodes, element nodes, and even comment nodes if there exist.
But for many tasks we don't want text or comment nodes. We want to manipulate element nodes that represent tags and form the structure of the page.
So let's see more navigation links that only take *element nodes* into account:

The links are similar to those given above, just with `Element` word inside:
- `children` -- only those children that are element nodes.
- `firstElementChild`, `lastElementChild` -- first and last element children.
- `previousElementSibling`, `nextElementSibling` -- neighbour elements.
- `parentElement` -- parent element.
````smart header="Why `parentElement`? Can the parent be *not* an element?"
The `parentElement` property returns the "element" parent, while `parentNode` returns "any node" parent. These properties are usually the same: they both get the parent.
With the one exception of `document.documentElement`:
```js run
alert( document.documentElement.parentNode ); // document
alert( document.documentElement.parentElement ); // null
```
The reason is that the root node `document.documentElement` (``) has `document` as its parent. But `document` is not an element node, so `parentNode` returns it and `parentElement` does not.
This detail may be useful when we want to travel up from an arbitrary element `elem` to ``, but not to the `document`:
```js
while(elem = elem.parentElement) { // go up till
alert( elem );
}
```
````
Let's modify one of the examples above: replace `childNodes` with `children`. Now it shows only elements:
```html run
Begin
End
...
```
## More links: tables [#dom-navigation-tables]
Till now we described the basic navigation properties.
Certain types of DOM elements may provide additional properties, specific to their type, for convenience.
Tables are a great example and a particularly important case for that.
**The ``** element supports (in addition to the given above) these properties:
- `table.rows` -- the collection of `` elements of the table.
- `table.caption/tHead/tFoot` -- references to elements ``, ``, `
`.
- `table.tBodies` -- the collection of `` elements (can be many according to the standard).
**``, ``, ``** elements provide the `rows` property:
- `tbody.rows` -- the collection of `` inside.
**`
`:**
- `tr.cells` -- the collection of `` and ` | ` cells inside the given ` |
`.
- `tr.sectionRowIndex` -- the position (index) of the given `
` inside the enclosing `/
/`.
- `tr.rowIndex` -- the number of the `` in the table as a whole (including all table rows).
**`` and ` | `:**
- `td.cellIndex` -- the number of the cell inside the enclosing ` |
`.
An example of usage:
```html run height=100
```
The specification: [tabular data](https://html.spec.whatwg.org/multipage/tables.html).
There are also additional navigation properties for HTML forms. We'll look at them later when we start working with forms.
# Summary
Given a DOM node, we can go to its immediate neighbours using navigation properties.
There are two main sets of them:
- For all nodes: `parentNode`, `childNodes`, `firstChild`, `lastChild`, `previousSibling`, `nextSibling`.
- For element nodes only: `parentElement`, `children`, `firstElementChild`, `lastElementChild`, `previousElementSibling`, `nextElementSibling`.
Some types of DOM elements, e.g. tables, provide additional properties and collections to access their content.