JavaScript DOM methods allow you to locate specific HTML elements on a page so you can read values, attach event listeners, or update UI text. Modern JavaScript relies primarily on getElementById(), querySelector(), and querySelectorAll().
Each DOM selector accepts either an element ID or a full CSS selector string. Choose static queries for predictable loops, and use closest() when walking upward from clicked child buttons:
| Method | Matches | Return Type | Live or Static? |
|---|---|---|---|
getElementById("id") |
Single ID | Element or null |
Single reference |
querySelector("css") |
First CSS match | Element or null |
Single reference |
querySelectorAll("css") |
All CSS matches | NodeList |
Static snapshot |
getElementsByClassName("c") |
Class name | HTMLCollection |
Live collection |
el.closest("css") |
Nearest ancestor | Element or null |
Walks upward |
A static NodeList captures matching elements at the moment you query, so adding or removing elements afterward will not shift indexes during a loop. A live HTMLCollection updates automatically whenever the DOM changes, which slows down tight loops and causes skipped items when removing elements.
Always check that querySelector() did not return null before reading properties, and use el.closest() inside delegated click listeners.
const appRoot = document.getElementById("app");
if (appRoot) {
appRoot.innerHTML = `
<ul class="task-list">
<li class="task-item active">Learn querySelector</li>
<li class="task-item">Build interactive UI</li>
</ul>
`;
const firstActive = appRoot.querySelector(".task-item.active");
const allItems = appRoot.querySelectorAll(".task-item");
console.log("First active:", firstActive?.textContent);
console.log("Total items:", allItems.length);
console.log("Parent list tag:", firstActive?.closest("ul")?.tagName);
}
# or . inside querySelector(): document.querySelector("header") looks for a <header> tag, not id="header" (#header) or class="header" (.header)..map() directly on querySelectorAll(): NodeList supports .forEach(), yet lacks .map() and .filter(). Convert it first with [...document.querySelectorAll(".card")].HTMLCollection: Because getElementsByClassName() updates live as elements leave the DOM, skipping indexes happens easily; prefer static querySelectorAll().getElementById() faster than querySelector("#id")?getElementById() is slightly faster in tight loops and needs no # prefix, though for normal UI setup both execute in microseconds.
querySelector() on a specific container instead of document?Yes! Calling modal.querySelector("button.save") scopes the search strictly inside modal, making components safer and faster.
el.closest(".card") return if el itself has class card?closest() checks the element itself first before walking up parent ancestors, so it returns el immediately.
Sign in to track your learning journey, earn industry-recognized certificates, and join our elite developer community.
Quick Access With
Experiment with the code from this lesson in our interactive playground.