20. JavaScript DOM Selecting Elements

What you will learn

  • How to find elements by id, class, tag, and CSS selector
  • The difference between one element and a list of elements
  • How to loop through a selection
  • How to move around the tree

Why select elements?

Before JavaScript can change anything on a page, it has to find the element. The methods below do that. The two most useful are querySelector and querySelectorAll, because they use the same CSS selectors you already know.

Overview of methods

Method Returns
getElementById("id") One element, or null
querySelector("selector") The first matching element, or null
querySelectorAll("selector") A list of all matching elements (it may be empty)
getElementsByClassName("class") A live list of elements with that class
getElementsByTagName("tag") A live list of elements with that tag

For new code, getElementById, querySelector, and querySelectorAll cover almost everything.

By id

Example

<h2 id="main-title">Original</h2>

<script>
  const title = document.getElementById("main-title");
  title.textContent = "Found by id";
</script>

Output (after the script runs)

Found by id

Notice there is no # in getElementById. You pass just the name.

By CSS selector

querySelector takes any CSS selector, including the # for ids, the dot for classes, and combinations. It returns the first match.

Example

<p class="note">First note</p>
<p class="note">Second note</p>
<div id="box"><p>Paragraph inside the box</p></div>

<script>
  document.querySelector(".note").style.color = "crimson";          // first note only
  document.querySelector("#box p").style.fontWeight = "bold";       // p inside #box
</script>

Output (after the script runs)

First note

Second note

Paragraph inside the box

Selecting many elements

querySelectorAll returns a list. Loop through it to change every match.

Example

<ul>
  <li class="item">One</li>
  <li class="item">Two</li>
  <li class="item">Three</li>
</ul>

<script>
  const items = document.querySelectorAll(".item");

  items.forEach(function (item, index) {
    item.textContent = (index + 1) + ". " + item.textContent;
    item.style.color = "#0d6efd";
  });
</script>

Output (after the script runs)

  • 1. One
  • 2. Two
  • 3. Three

A list from querySelectorAll supports forEach and for...of, and has a length. To use array methods such as map or filter, first convert it with Array.from(items).

One or many: the classic mistake

querySelectorAll returns a list, so this fails:

Example: this does not work

document.querySelectorAll(".item").style.color = "red";   // Error: a list has no style

Loop through the list instead, or use querySelector when you want just one.

Always check for null

If nothing matches, getElementById and querySelector return null, and using it crashes the script. Guard against it when an element might not exist:

Example

<p id="demo"></p>

<script>
  const missing = document.querySelector("#does-not-exist");

  if (missing) {
    missing.textContent = "Found it";
  } else {
    document.getElementById("demo").textContent = "That element is not on this page.";
  }
</script>

Output (after the script runs)

That element is not on this page.

Searching inside an element

You can call querySelector on any element to search only inside it.

Example

<div id="a"><p class="msg">Message in A</p></div>
<div id="b"><p class="msg">Message in B</p></div>

<script>
  const box = document.getElementById("b");
  box.querySelector(".msg").style.background = "yellow";   // only inside #b
</script>

Output (after the script runs)

Message in A

Message in B

Moving around the tree

From one element you can reach its relatives.

Property Gives you
parentElement The parent element
children The child elements
firstElementChild, lastElementChild First and last child element
nextElementSibling, previousElementSibling The element after and before
closest("selector") The nearest ancestor that matches

Example

<ul id="list">
  <li>One</li>
  <li id="two">Two</li>
  <li>Three</li>
</ul>
<p id="demo"></p>

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

  document.getElementById("demo").innerHTML =
    "Parent id: " + two.parentElement.id + "<br>" +
    "Before: " + two.previousElementSibling.textContent + "<br>" +
    "After: " + two.nextElementSibling.textContent + "<br>" +
    "Items in the list: " + two.parentElement.children.length;
</script>

Output (after the script runs)

  • One
  • Two
  • Three

Parent id: list
Before: One
After: Three
Items in the list: 3

Common mistakes

  • Adding # or . to getElementById. It takes the bare name.
  • Forgetting the # or . in querySelector.
  • Treating the list from querySelectorAll as a single element.
  • Not checking for null when the element may be missing.
  • Running the script before the elements exist.

Exercise

Select every paragraph with the class tip and give each a lightyellow background. The normal paragraph must stay unchanged.

Show solution
<p class="tip">Tip one</p>
<p class="tip">Tip two</p>
<p>Normal text</p>

<script>
  const tips = document.querySelectorAll(".tip");

  tips.forEach(function (tip) {
    tip.style.backgroundColor = "lightyellow";
  });
</script>

Knowledge check

1. Which method returns only the first match for a CSS selector?

querySelector()

2. What does querySelector return when nothing matches?

null

3. Why does document.querySelectorAll(".x").style.color = "red" fail?

It returns a list, and a list has no style. You must loop through it.

Summary

  • Use getElementById, querySelector, and querySelectorAll to find elements.
  • Remember: one element or a list, and check for null.
  • Reach relatives with parentElement, children, and sibling properties.
Scroll to Top