Selecting Elements
Learn how to find and select HTML elements from the DOM using JavaScript.
Selecting Elements
Before JavaScript can do anything to an element — change its text, add a style, listen for a click — it first needs to find that element in the DOM.
Selecting elements is the first step in every DOM operation. JavaScript gives you several methods to do this, each suited for different situations.
The HTML We Will Use
All examples in this topic work against this simple HTML structure:
<!DOCTYPE html>
<html>
<body>
<h1 id="title">Welcome to DocsHub</h1>
<div class="card">
<h2 class="card-title">JavaScript</h2>
<p class="description">The language of the web.</p>
</div>
<div class="card">
<h2 class="card-title">Python</h2>
<p class="description">Great for data and backends.</p>
</div>
<ul id="list">
<li class="item">Variables</li>
<li class="item">Functions</li>
<li class="item">Arrays</li>
</ul>
<button id="submit-btn" data-action="submit">Submit</button>
</body>
</html>getElementById() — Select by ID
Selects a single element by its id attribute. IDs are unique on a page — there should only ever be one element with a given ID. Returns the element or null if not found.
const title = document.getElementById("title");
console.log(title); // <h1 id="title">Welcome to DocsHub</h1>
const list = document.getElementById("list");
console.log(list); // <ul id="list">...</ul>
const missing = document.getElementById("nothing");
console.log(missing); // null — not foundThis is the fastest selector — when you know the exact ID, use this.
querySelector() — Select by CSS Selector
Selects the first element that matches any CSS selector. This is the most flexible method — anything you can select in CSS, you can select here.
// By tag name
const h1 = document.querySelector("h1");
// By ID — note the #
const title = document.querySelector("#title");
// By class — note the .
const card = document.querySelector(".card"); // first card only
// By attribute
const btn = document.querySelector("[data-action='submit']");
// Nested selector — p inside .card
const desc = document.querySelector(".card p");
// First list item
const firstItem = document.querySelector("#list .item");querySelector() always returns a single element — the first match. If nothing matches, it returns null.
querySelectorAll() — Select Multiple Elements
Selects all elements that match a CSS selector. Returns a NodeList — similar to an array but not exactly one. Contains all matches, or an empty NodeList if nothing found.
// All cards
const cards = document.querySelectorAll(".card");
console.log(cards); // NodeList(2) [div.card, div.card]
console.log(cards.length); // 2
// All list items
const items = document.querySelectorAll(".item");
console.log(items.length); // 3
// All paragraphs inside cards
const descriptions = document.querySelectorAll(".card p");Looping through a NodeList
A NodeList is not an array — but you can loop through it with forEach() or for...of:
const items = document.querySelectorAll(".item");
// forEach
items.forEach(item => {
console.log(item.textContent);
});
// for...of
for (const item of items) {
console.log(item.textContent);
}To use full array methods like map() and filter(), convert it to an array first:
const itemsArray = Array.from(document.querySelectorAll(".item"));
const texts = itemsArray.map(item => item.textContent);
console.log(texts); // ["Variables", "Functions", "Arrays"]Or use spread:
const itemsArray = [...document.querySelectorAll(".item")];getElementsByClassName() — Select by Class
Returns an HTMLCollection of all elements with a given class name. Live — updates automatically if the DOM changes.
const cards = document.getElementsByClassName("card");
console.log(cards.length); // 2In modern JavaScript, querySelectorAll() is preferred over getElementsByClassName() and getElementsByTagName(). It is more flexible, consistent, and returns a static snapshot rather than a live collection. Use querySelector and querySelectorAll for all your selecting needs.
getElementsByTagName() — Select by Tag
Returns an HTMLCollection of all elements with a given tag name.
const paragraphs = document.getElementsByTagName("p");
console.log(paragraphs.length); // 2
const allDivs = document.getElementsByTagName("div");Again — prefer querySelectorAll("p") in modern code.
Selecting Relative to an Element
You do not always have to search the entire document. Once you have an element, you can search within it or navigate to its relatives.
Searching within an element
const firstCard = document.querySelector(".card");
// Find elements inside firstCard only
const title = firstCard.querySelector(".card-title");
const desc = firstCard.querySelector("p");
console.log(title.textContent); // JavaScript
console.log(desc.textContent); // The language of the web.This is useful when you have multiple similar structures — search within a specific one instead of the whole page.
Navigating relatives
Every element knows about its family in the DOM tree.
const list = document.getElementById("list");
// Children — direct child elements
console.log(list.children); // HTMLCollection of li elements
console.log(list.children[0]); // first li
console.log(list.children.length); // 3
// First and last child element
console.log(list.firstElementChild); // first li
console.log(list.lastElementChild); // last li
// Parent
const item = document.querySelector(".item");
console.log(item.parentElement); // the ul
// Siblings
console.log(item.nextElementSibling); // next li
console.log(item.previousElementSibling); // previous li — null for first itemChecking What You Selected
Always verify your selection before using it — especially when the element might not exist.
const element = document.querySelector(".something");
if (element) {
// safe to use
console.log(element.textContent);
} else {
console.log("Element not found");
}Or use optional chaining:
const text = document.querySelector(".something")?.textContent ?? "Not found";
console.log(text);Reading Element Information
Once you have an element, you can read information about it.
const btn = document.getElementById("submit-btn");
// Tag name
console.log(btn.tagName); // "BUTTON"
// ID and class
console.log(btn.id); // "submit-btn"
console.log(btn.className); // "btn primary" (if it had classes)
// Attributes
console.log(btn.getAttribute("data-action")); // "submit"
console.log(btn.hasAttribute("disabled")); // false
// Text content
console.log(btn.textContent); // "Submit"
// HTML content
console.log(btn.innerHTML); // "Submit" (or nested HTML if any)document.querySelector vs document.getElementById
Both select a single element. Here is when to use which:
// getElementById — faster, only works for IDs
const title = document.getElementById("title");
// querySelector — flexible, works for anything
const title = document.querySelector("#title");
const title = document.querySelector("h1");
const title = document.querySelector(".hero h1");getElementById | querySelector | |
|---|---|---|
| Selects by | ID only | Any CSS selector |
| Returns | Element or null | Element or null |
| Speed | Slightly faster | Slightly slower |
| Flexibility | Low | High |
| Use when | You have a simple ID | You need any selector |
For simple ID selection getElementById is fine. For everything else use querySelector.
A Real Example — Building a Mini Search
<input id="search" type="text" placeholder="Search topics...">
<ul id="topics">
<li class="topic">Variables</li>
<li class="topic">Functions</li>
<li class="topic">Arrays</li>
<li class="topic">Objects</li>
<li class="topic">Async JavaScript</li>
</ul>const searchInput = document.getElementById("search");
const topics = document.querySelectorAll(".topic");
searchInput.addEventListener("input", () => {
const query = searchInput.value.toLowerCase();
topics.forEach(topic => {
const matches = topic.textContent.toLowerCase().includes(query);
topic.style.display = matches ? "list-item" : "none";
});
});querySelectorAll gets all topics as a NodeList. As the user types, each topic is shown or hidden based on whether its text matches the search query. Real, working search in 10 lines.
Summary
getElementById("id")— fastest, selects one element by exact IDquerySelector("selector")— selects the first match of any CSS selectorquerySelectorAll("selector")— selects all matches, returns a NodeList- Prefer
querySelectorandquerySelectorAllover older methods in modern code - NodeList is not an array — use
forEach,for...of, or convert withArray.from() - Search within a specific element by calling
querySelectoron it instead ofdocument - Navigate relatives with
parentElement,children,nextElementSibling,previousElementSibling - Always check if the element exists before using it — selections can return
null