The DOM: Selecting Elements

When a browser loads HTML, it builds a tree of objects in memory called the Document Object Model, or DOM. Each tag becomes an object JavaScript can read and change. The first step in any page interaction is finding the right element — this lesson covers every way to do it.

The document tree

Given this HTML:

HTML page.html
<body>
  <h1 id="title">Recipes</h1>
  <ul class="list">
    <li class="item">Soup</li>
    <li class="item featured">Salad</li>
  </ul>
</body>

the browser creates a tree: document at the top, then <html>, <body>, and so on. Each element is a node with a parent, children and siblings. The global document object is your entry point to all of it.

querySelector and querySelectorAll

These take any CSS selector — the same syntax you use in stylesheets:

Try it yourself
Result
  • querySelector returns the first matching element, or null if none match.
  • querySelectorAll returns a NodeList of all matches (possibly empty).

Working with a NodeList

A NodeList isn't an array, but it supports forEach, length, indexing and for…of. For other array methods, convert it first:

Try it yourself
Result

Older selection methods

MethodReturnsNotes
getElementById("title")One element or nullVery fast; no # in the argument
getElementsByClassName("item")Live HTMLCollectionNo dot in the argument
getElementsByTagName("li")Live HTMLCollection

A live collection updates automatically as the page changes, which can cause surprises in loops that add or remove elements. querySelectorAll returns a static snapshot. Most modern code uses querySelector/querySelectorAll for consistency.

Searching inside an element

Every element has its own querySelector methods that only search its descendants — useful when a page has repeated components:

Try it yourself
Result

Walking the tree

From any element, you can move to related elements:

Property / methodGives
parentElementThe parent element
childrenChild elements
firstElementChild, lastElementChildFirst/last child element
nextElementSibling, previousElementSiblingNeighbouring elements
closest(selector)The nearest ancestor (or itself) matching a selector
matches(selector)Whether the element matches a selector
Try it yourself
Result

closest is especially handy in event handlers, to get from the clicked element up to the component it belongs to (lesson 45).

Always check for null

If a selector doesn't match anything — a typo, or the script ran before the element existed — querySelector returns null, and using the result crashes with "Cannot read properties of null". Check, or use optional chaining:

JS null-check.js
const banner = document.querySelector("#promo-banner");
if (banner) {
  banner.hidden = false;
}
document.querySelector("#maybe")?.classList.add("active");

And make sure your script runs after the HTML exists, using defer or type="module" (lesson 02).

Try it yourself

Change the selectors to highlight different elements:

Try it yourself
Result