CodingNic

The DOM

DOM Traversal

The DOM 20 min read

DOM Traversal

Objectives

By the end of this chapter, you should be able to:

  • Move from a child element to its parent with .parentElement
  • Access an element’s children with .children
  • Move sideways between elements with .nextElementSibling and .previousElementSibling
  • Find the nearest matching ancestor with .closest()

💡 Why this matters: You won’t always have a direct selector for the exact element you need. Traversal lets you start from an element you can select and move to a nearby one you can’t.

Every example in this lesson uses this same HTML:

text
<div class="card">
  <h2>Title</h2>
  <p>First</p>
  <p>Second</p>
  <button class="delete">Delete</button>
</div>

Moving Up: .parentElement

Every element has a .parentElement, the element directly containing it.

javascript
const button = document.querySelector(".delete");
console.log(button.parentElement.className);
// card

This is common when handling a click on a small element (like a delete button) and needing to act on the larger element it belongs to (like the whole card).

Moving Down: .children

.children gives you an element’s direct child elements (not grandchildren, and not text nodes, only actual elements).

javascript
const card = document.querySelector(".card");
console.log(card.children.length);
// 4

for (const child of card.children) {
  console.log(child.tagName);
}
// H2
// P
// P
// BUTTON

.tagName is always uppercase, regardless of how you wrote the tag in your HTML.

Moving Sideways: Siblings

.nextElementSibling and .previousElementSibling move between elements that share the same parent.

javascript
const firstP = document.querySelector("p");
console.log(firstP.nextElementSibling.textContent);
// Second

console.log(firstP.previousElementSibling.tagName);
// H2

Starting from the first <p>, its next sibling is the second <p>, and its previous sibling is the <h2> before it. If there’s no matching sibling, either property is null, so check before using the result.

Finding the Nearest Ancestor: .closest()

.closest(selector) starts at an element and walks upward through its ancestors, returning the first one that matches the selector, or null if none do.

javascript
const closestCard = button.closest(".card");
console.log(closestCard === card);
// true

This is the more reliable version of .parentElement when you’re not sure exactly how many levels up the element you want is, or when the structure might change. Instead of chaining .parentElement.parentElement, .closest() searches until it finds a match.

Try It

  1. Given a <div class="card"> containing an <h3> and a <button>, select the button and use .parentElement to log the card’s class name.
  2. Given a <ul> with three <li> children, select the <ul> and use .children to log how many there are and each one’s .tagName.
  3. Select the first <li> in that list and use .nextElementSibling to log the second one’s text.
  4. Nest a <button> two levels inside a <div class="panel">. Select the button and use .closest(".panel") to reach the outer div directly.

Recap

  • .parentElement moves up one level.
  • .children gives you an element’s direct child elements.
  • .nextElementSibling and .previousElementSibling move between elements sharing a parent, and are null when there’s nothing there.
  • .closest(selector) walks upward until it finds a matching ancestor, useful when you don’t know exactly how many levels away it is.

Next lesson: reading values out of forms.