JS DOM Navigation
In this page:
Navigating to a Parent Element
.parentElement returns an element's direct parent in the DOM tree -- useful for walking upward, like finding the containing card or list item of a button that was clicked, without needing to have selected that ancestor directly.
Note: Use .parentElement (which returns an Element or null) rather than the older .parentNode when you specifically want an Element result, not any node type.
Warning: Calling .parentElement on the root <html> element returns null, since it has no parent element -- code walking upward repeatedly should account for eventually hitting that boundary.
Example: Navigating to a Parent Element
<div id="parent"><button id="child">Click</button></div>
<script>
const child = document.getElementById("child");
console.log(child.parentElement.id);
</script>
Navigating to Child Elements
.children returns a live collection of an element's direct child elements (excluding text and comment nodes), and .firstElementChild / .lastElementChild jump directly to the first or last of those children, without needing to index into the full collection.
Note: Use .children instead of .childNodes when you specifically want only element children, skipping whitespace text nodes that often sit between tags in formatted HTML.
Warning: .firstElementChild and .lastElementChild return null if the element has no child elements at all, even if it contains text content.
Example: Navigating to Child Elements
<ul id="list"><li>A</li><li>B</li></ul>
<script>
const list = document.getElementById("list");
console.log(list.children.length);
console.log(list.firstElementChild.textContent);
console.log(list.lastElementChild.textContent);
</script>
Navigating to Sibling Elements
.nextElementSibling and .previousElementSibling move to the adjacent element at the same tree level, in either direction -- useful for relative operations, like highlighting the item right after the one a user clicked.
Note: Use these sibling properties when an operation genuinely depends on tree position relative to a known element, rather than re-querying the whole document.
Warning: The first element in a group has no previousElementSibling (returns null), and the last has no nextElementSibling (also null) -- always guard against this at the boundaries.
Example: Navigating to Sibling Elements
<ul><li id="first">A</li><li id="second">B</li></ul>
<script>
const first = document.getElementById("first");
console.log(first.nextElementSibling.textContent);
</script>
Navigating Relative to an Event Target
Combining event.target (the element that triggered an event) with navigation properties lets you find and manipulate related elements without needing separate IDs for everything -- like finding a delete button's containing list item to remove it, working purely from tree relationships.
Note: Use relative navigation from event.target for components with repeated structure (like list items), avoiding the need to assign unique IDs to every single related element.
Warning: Navigating from event.target assumes a specific, consistent tree structure -- if the HTML structure changes later, navigation code written around it can silently break.
Example: Navigating Relative to an Event Target
<ul>
<li>Item <button class="del">X</button></li>
</ul>
<script>
document.querySelector(".del").addEventListener("click", (e) => {
console.log(e.target.parentElement.textContent);
});
</script>
Navigation vs Re-querying: Which to Use
Navigation properties are ideal when you already have a reference to a nearby element and just need to move relative to it -- re-running querySelector() from the document root makes more sense when you need to find something unrelated to any element you currently hold a reference to.
Note: Reach for a navigation property when the target element's position relative to one you already have is known and stable; use querySelector for anything else.
Warning: Chaining many navigation properties together (parentElement.parentElement.nextElementSibling.firstElementChild) to reach a distant element makes code fragile and hard to read -- a targeted selector is often clearer.
Example: Navigation vs Re-querying: Which to Use
<div id="card"><button id="btn">Click</button></div>
<script>
document.getElementById("btn").parentElement;
console.log(document.querySelector("#card"));
</script>
- Using the non-Element-specific properties (childNodes, nextSibling) when you specifically want element-only navigation, since those include text nodes (like whitespace) that childNodes and nextSibling do not filter out.
- Assuming a navigation property always returns something -- .nextElementSibling on the last child, or .parentElement on the document root, returns null, and code needs to handle that.
- Re-querying the DOM with querySelector when a simple navigation property (like .parentElement) would find the same element with less overhead.
- parentElement, children, firstElementChild, and lastElementChild navigate to related elements, skipping over text/comment nodes.
- nextElementSibling and previousElementSibling move to adjacent sibling elements at the same tree level.
- These properties can return null when there is nothing in that direction, so checking before using the result matters.
All Element-based DOM navigation properties are supported in every modern browser.
Chapter Quiz — Complete all 26 topics to unlock
0/26 topics done
Complete these topics first:
- JS Dates
- JS Math
- JS Conditionals
- JS Switch
- JS Loop For
- JS Loop While
- JS Iterables
- JS Sets
- JS Maps
- JS typeof
- JS Type Conversion
- JS Destructuring
- JS Arrow Functions
- JS Classes
- JS Modules
- JS Promises
- JS Async/Await
- JS DOM
- JS DOM Methods
- JS Events Advanced
- JS DOM Navigation
- JS DOM Collections
- JS Async Callbacks
- JS Async Parallel
- JS Date Set
- JS Set Logic