Loading...
Loading...
Find anything on the page. The first step to DOM manipulation.
The Document Object Model is how JavaScript reads and changes web pages. Selecting elements, modifying content, handling events, validating forms, and persisting data in storage are the core skills of frontend development.
Learn Selecting Elements in JavaScript — covering querySelector, querySelectorAll, By ID, Class, Tag, DOM Traversal with interactive visual examples and step-by-step explanations.
JavaScript in the browser is all about the DOM — the live tree of HTML elements your code can select, modify, and respond to. Click handlers, form validation, dynamic content updates, and local storage all build on DOM APIs.
This module takes you from querySelector to full user interaction patterns. You will learn event delegation, form handling, and how to persist state in localStorage — the skills every frontend developer uses daily.
Understanding selecting elements is essential for every JavaScript developer. It shows up in frontend UI code, backend APIs, and framework internals — and getting it wrong leads to bugs that are hard to trace. This chapter builds intuition with visuals so the behavior sticks.
Find the FIRST element matching a CSS selector.
// By class: const card = document.querySelector(".card"); // By ID: const app = document.querySelector("#app"); // By tag: const firstParagraph = document.querySelector("p"); // Complex selectors: const activeLink = document.querySelector("nav a.active"); const firstItem = document.querySelector("ul > li:first-child");
querySelector accepts any valid CSS selector. Returns the first match or null if nothing is found.
Find ALL elements matching a selector.
// Returns a NodeList (array-like, not a true array): const items = document.querySelectorAll("li"); items.length; // number of matches items[0]; // first element items[2]; // third element // NodeList supports forEach: items.forEach(item => { item.classList.add("styled"); }); // Convert to array for map/filter/reduce: const arr = [...items]; // spread // or: Array.from(items) const active = arr.filter(el => el.classList.contains("active")); const texts = arr.map(el => el.textContent);
💡 querySelectorAll returns a staticNodeList — a snapshot. If elements are added/removed later, the NodeList doesn't update.
Older methods — still useful in specific cases.
// By ID (fastest — IDs are unique): const el = document.getElementById("app"); // No # prefix! Returns element or null. // By class name (returns live HTMLCollection): const cards = document.getElementsByClassName("card"); // No dot prefix! // By tag name (returns live HTMLCollection): const paragraphs = document.getElementsByTagName("p"); // These return LIVE collections — they auto-update! // If you add a <p>, paragraphs.length increases.
| Method | Returns | Live? |
|---|---|---|
| querySelector | Element | null | — |
| querySelectorAll | static NodeList | No |
| getElementById | Element | null | — |
| getElementsByClassName | live HTMLCollection | Yes |
| getElementsByTagName | live HTMLCollection | Yes |
Navigate between related elements.
const el = document.querySelector(".current"); // Parent: el.parentElement; // direct parent element el.closest(".wrapper"); // nearest ancestor matching selector // Children: el.children; // direct child elements (HTMLCollection) el.firstElementChild; // first child element el.lastElementChild; // last child element el.childElementCount; // number of children // Siblings: el.nextElementSibling; // next sibling element el.previousElementSibling; // previous sibling element // Example — highlight all siblings: let sibling = el.parentElement.firstElementChild; while (sibling) { if (sibling !== el) sibling.classList.add("dim"); sibling = sibling.nextElementSibling; }
⚠️ Use parentElement / children (elements only), not parentNode / childNodes (includes text/comment nodes).
Some collections update automatically, others don't.
// STATIC (snapshot — doesn't update): const items = document.querySelectorAll("li"); console.log(items.length); // 3 document.querySelector("ul").innerHTML += "<li>New</li>"; console.log(items.length); // still 3! (stale) // LIVE (auto-updates): const items2 = document.getElementsByTagName("li"); console.log(items2.length); // 3 document.querySelector("ul").innerHTML += "<li>New</li>"; console.log(items2.length); // 4! (auto-updated) // ⚠️ Live collections can cause infinite loops: // for (let i = 0; i < liveList.length; i++) { // liveList[i].className = "x"; // if this adds matches... // } // Prefer static querySelectorAll for iteration.
Common questions about selecting elements.