Selecting Elements
Before you can read or change anything on the page, you need to get a reference to the element you want to work with. Selecting an element means asking the DOM: give me this specific node.
document.querySelector()
Section titled “document.querySelector()”querySelector accepts any CSS selector and returns the first matching element. If nothing matches, it returns null.
const nav = document.querySelector('nav');const heading = document.querySelector('h1');const firstCard = document.querySelector('.tour-card');const submitBtn = document.querySelector('#contact-form button[type="submit"]');This is the most flexible selector — it accepts the same syntax as CSS, so any selector you already know works here. Use it as your default for selecting a single element.
document.querySelectorAll()
Section titled “document.querySelectorAll()”querySelectorAll accepts any CSS selector and returns a NodeList of all matching elements:
const allCards = document.querySelectorAll('.tour-card');const allImages = document.querySelectorAll('img');const navLinks = document.querySelectorAll('nav a');
console.log(allCards.length); // number of tour cards on the pageA NodeList is iterable — you can use for...of to loop over the results:
for (const card of allCards) { console.log(card.textContent);}Use querySelectorAll as your default for selecting multiple elements.
document.getElementById()
Section titled “document.getElementById()”getElementById selects a single element by its id attribute. It is fast and widely used in older code:
const contactForm = document.getElementById('contact-form');Note: no # prefix — just the id string, unlike querySelector('#contact-form').
querySelector('#contact-form') and getElementById('contact-form') return the same element. For new code, querySelector is preferred because it accepts any selector and is consistent with querySelectorAll.
document.getElementsByClassName()
Section titled “document.getElementsByClassName()”getElementsByClassName returns a live HTMLCollection of elements with a given class:
const cards = document.getElementsByClassName('tour-card');This is an older API. Prefer querySelectorAll('.tour-card') for new code — it returns a static NodeList and accepts any CSS selector.
NodeList vs HTMLCollection
Section titled “NodeList vs HTMLCollection”| NodeList | HTMLCollection | |
|---|---|---|
| Returned by | querySelectorAll | getElementsBy* |
| Updates automatically? | No (static snapshot) | Yes (live) |
Iterable with for...of? | Yes | Yes |
Has .forEach()? | Yes | No |
The “live” behavior of HTMLCollection means it updates automatically when the DOM changes — which can cause subtle bugs when you are modifying elements during iteration. Stick to querySelectorAll to avoid this.
Null checks
Section titled “Null checks”When querySelector or getElementById does not find a match, it returns null. Calling any method on null throws a TypeError:
const nav = document.querySelector('nav');nav.classList.add('loaded'); // TypeError if nav is nullFor elements you are confident exist, this is not a concern. For elements that might be absent depending on the page, check first:
const nav = document.querySelector('nav');if (nav) { nav.classList.add('loaded');}In the STO project with defer on your script, all elements are guaranteed to exist when the script runs. Null checks matter most when code runs on multiple pages where an element might not always be present.
Exercise
Section titled “Exercise”On the STO site, open the Console and run each selector:
// Single element selectorsconst nav = document.querySelector('nav');console.log(nav);
const mainHeading = document.querySelector('h1');console.log(mainHeading);
// Multiple element selectorconst tourCards = document.querySelectorAll('.tour-card');console.log(tourCards.length);
for (const card of tourCards) { console.log(card.querySelector('h3')?.textContent);}
// Check for nullconst missing = document.querySelector('.does-not-exist');console.log(missing); // nullInspect each result in the Elements panel by hovering over the logged element in the console.
document.querySelector(selector)returns the first matching element ornull. Use it for single elements.document.querySelectorAll(selector)returns a static NodeList of all matches. Usefor...ofto iterate. Use it for multiple elements.document.getElementById(id)selects by id without a#prefix —querySelectoris preferred for new code.getElementsByClassNamereturns a live HTMLCollection — preferquerySelectorAllto avoid live-update surprises.- Always check for
nullbefore calling methods on elements that may not exist on every page.