Skip to main content

Finding elements on the page

Before you can change anything on a page, you need to find it. JavaScript gives you two main methods — both use CSS selectors, so if you know CSS, you already know how to use them.

document.querySelector()

Returns the first element that matches a CSS selector:
If no element matches, querySelector returns null — not an error.
querySelector returns null when it can’t find a match. Always check for null if you’re not 100% sure the element exists, or you’ll get TypeError: Cannot read properties of null.

document.querySelectorAll()

Returns all matching elements as a NodeList:

Iterating over results

querySelectorAll returns a NodeList, not an array. It has .forEach() but not .map(), .filter(), etc. Spread it into an array with [...nodeList] when you need array methods.

Common CSS selectors

You use the same selectors as CSS. Here’s a quick reference:

Practical examples

Use data-* attributes to select elements meant for JavaScript interaction. This keeps your JS selectors separate from your CSS classes: <button data-action="delete"> instead of <button class="delete-btn">.

Older methods (still common)

You’ll see these in older code and tutorials:
querySelector / querySelectorAll are the modern standard. They’re more flexible (any CSS selector) and more consistent (querySelectorAll always returns a static NodeList).

Scope your selectors

You can call querySelector on any element, not just document:
This is useful when you have multiple similar structures on the page and need to target elements within a specific container.

Common mistakes

Scripts in <head> run before <body> is parsed. Use defer on your script tag, or place the <script> at the bottom of <body>. The defer approach is modern and preferred.

What’s next?

You can find elements. Now let’s change them — text, styles, classes, and attributes.

Modifying elements

Change text, styles, attributes, and classes