Skip to main content

JavaScript DOM

JavaScript DOM Traversal

Written by Published

DOM traversal moves from one element to its parent, children or siblings.

Once you have one element, you can reach the ones around it.

This matters most in event handling, where you know which element was clicked.

Example

Example

javascript

document.body.innerHTML = '<div id="box"><p id="demo">Text</p></div>';

const p = document.getElementById("demo");

console.log(p.parentElement.id);

The output is box.

Moving Around the Tree

parentElement goes up one level.

children, firstElementChild and lastElementChild go down.

nextElementSibling and previousElementSibling go sideways.

Syntax

Syntax

javascript

element.parentElement;
element.children;
element.nextElementSibling;

The Element versions skip text and whitespace nodes.

Going Down

children is a live collection of the child elements.

Example

Example

javascript

document.body.innerHTML =
  '<ul id="list"><li>A</li><li>B</li><li>C</li></ul>';

const list = document.getElementById("list");

console.log(list.children.length);
console.log(list.firstElementChild.textContent);
console.log(list.lastElementChild.textContent);

The output is 3, then A, then C.

Going Sideways

Siblings share the same parent.

Example

Example

javascript

document.body.innerHTML =
  '<ul><li>A</li><li id="middle">B</li><li>C</li></ul>';

const middle = document.getElementById("middle");

console.log(middle.previousElementSibling.textContent);
console.log(middle.nextElementSibling.textContent);

The output is A then C.

Why Element Versions Matter

childNodes and nextSibling include text nodes.

The whitespace between tags counts as a text node, which trips people up.

Example

Example

javascript

document.body.innerHTML = "<div id='box'>\n  <p>One</p>\n</div>";

const box = document.getElementById("box");

console.log(box.children.length);
console.log(box.childNodes.length > box.children.length);

childNodes is larger because of the whitespace.

closest

closest walks up the tree looking for a match.

It checks the element itself first, then each ancestor.

Example

Example

javascript

document.body.innerHTML =
  '<div class="card"><p><span id="tag">Here</span></p></div>';

const tag = document.getElementById("tag");

console.log(tag.closest(".card").className);

This is extremely useful with event delegation.

Nothing There Gives null

The first child of an empty element, or the sibling after the last one, is null.

Example

Example

javascript

document.body.innerHTML = '<ul id="list"><li id="only">A</li></ul>';

const only = document.getElementById("only");

console.log(only.nextElementSibling === null ? "no sibling" : "has one");

Guard before reading a property from a traversal result.

Complete Example

Complete Example

html

<!DOCTYPE html>
<html>
<head>
  <title>JavaScript DOM Traversal</title>
</head>
<body>

  <h1>DOM Traversal</h1>

  <ul id="list">
    <li>First</li>
    <li id="middle">Middle</li>
    <li>Last</li>
  </ul>

  <p id="out"></p>

  <script>
    const middle = document.getElementById("middle");

    document.getElementById("out").textContent =
      "Parent: " + middle.parentElement.id +
      " / Before: " + middle.previousElementSibling.textContent +
      " / After: " + middle.nextElementSibling.textContent;
  </script>

</body>
</html>

Try It Yourself

Run the above example in the Try It Editor.

Try closest:

Use middle.closest("ul").id to walk up to the list.

Important Points

  • parentElement moves up one level.
  • children holds the child elements.
  • nextElementSibling and previousElementSibling move sideways.
  • The Element versions skip whitespace text nodes.
  • closest searches upwards for a matching ancestor.

Conclusion

Traversal lets one reference reach everything around it.

The Element properties are almost always the ones you want.

closest becomes essential once you reach event delegation.