Selecting Elements
What does it mean to select elements?
Selecting elements means asking the browser for one or more elements from the DOM so your JavaScript can read them, update them, or attach event listeners.
Smallest working example
<button id="saveButton">Save</button>
const button = document.querySelector("#saveButton");
if (button) {
button.textContent = "Saved";
}
Why selecting elements matters
Before you can manipulate elements with JavaScript, you need to select them and store a reference.
JavaScript provides several methods for selecting elements, each with different use cases.
getElementById()
Selects a single element by its id attribute.
<button id="myButton">Click me</button>
const button = document.getElementById("myButton");
if (button) {
button.textContent = "Clicked!";
}
Returns: A single element (or null if not found)
Use when: You need one specific element with an ID.
Note: IDs must be unique on a page. If multiple elements have the same ID, only the first is returned.
getElementsByClassName()
Selects all elements with a specific class name.
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
const items = document.getElementsByClassName("item");
console.log(items.length); // 3
// Loop through items
for (let i = 0; i < items.length; i++) {
items[i].style.color = "blue";
}
Returns: A live HTMLCollection (updates automatically when DOM changes)
Use when: You need all elements with a specific class.
Note: Returns a collection (array-like), not a single element. Use array methods carefully (see below).
getElementsByTagName()
Selects all elements with a specific tag name.
<p>Paragraph 1</p>
<p>Paragraph 2</p>
<p>Paragraph 3</p>
const paragraphs = document.getElementsByTagName("p");
console.log(paragraphs.length); // 3
paragraphs[0].textContent = "First paragraph";
Returns: A live HTMLCollection
Use when: You need all elements of a specific type (all <p>, all <div>, etc.).
querySelector()
Selects the first element matching a CSS selector.
<div class="container">
<p class="highlight">First paragraph</p>
<p class="highlight">Second paragraph</p>
</div>
// Select by class
const first = document.querySelector(".highlight");
if (first) {
console.log(first.textContent); // "First paragraph"
}
// Select by ID
const container = document.querySelector("#container");
// Select by tag
const div = document.querySelector("div");
// Complex selectors
const firstInContainer = document.querySelector(".container .highlight");
Returns: A single element (or null if not found)
Use when: You need one element and want the flexibility of CSS selectors.
This is the modern, preferred method for most use cases.
querySelectorAll()
Selects all elements matching a CSS selector.
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item special">Item 3</div>
// Select all items
const items = document.querySelectorAll(".item");
console.log(items.length); // 3
// Select specific items
const special = document.querySelectorAll(".item.special");
console.log(special.length); // 1
// Use forEach (works with NodeList)
items.forEach(item => {
item.style.color = "blue";
});
Returns: A static NodeList (snapshot, doesn't update when DOM changes)
Use when: You need multiple elements and want CSS selector flexibility.
This is the modern, preferred method for selecting multiple elements.
When to prefer querySelector
querySelector and querySelectorAll are preferred in modern JavaScript because:
1. Flexibility
CSS selectors are powerful and flexible:
// Select first child
document.querySelector(".container > :first-child");
// Select elements with attribute
document.querySelector('[data-id="123"]');
// Select based on multiple conditions
document.querySelector("button.primary:not(.disabled)");
2. Consistency
Both methods use the same selector syntax:
// Single element
document.querySelector(".item");
// Multiple elements
document.querySelectorAll(".item");
3. Works with NodeList
querySelectorAll returns a NodeList that supports forEach:
document.querySelectorAll(".item").forEach(item => {
console.log(item.textContent);
});
4. Better for modern code
Most modern code uses querySelector/querySelectorAll.
Recommendation: Use querySelector/querySelectorAll for most cases. Use getElementById when you specifically need the fastest ID lookup (though the difference is usually negligible).
Rule of thumb: use querySelector() for one element, querySelectorAll() for multiple elements, and getElementById() when an ID lookup is the clearest choice.
Common mistakes when selecting elements
Mistake 1: Forgetting elements might not exist
// Bad: assumes element exists
const button = document.getElementById("myButton");
button.addEventListener("click", () => {
console.log("Clicked");
}); // Error if button is null!
// Good: check first
const button = document.getElementById("myButton");
if (button) {
button.addEventListener("click", () => {
console.log("Clicked");
});
}
Mistake 2: Using array methods on HTMLCollection
// Bad: HTMLCollection doesn't have forEach
const items = document.getElementsByClassName("item");
items.forEach(item => {}); // Error!
// Good: convert to array or use querySelectorAll
const itemsArray = Array.from(document.getElementsByClassName("item"));
itemsArray.forEach(item => {});
// Or use querySelectorAll (NodeList has forEach)
document.querySelectorAll(".item").forEach(item => {});
Mistake 3: Selecting before DOM is ready
// Bad: script runs before DOM loads
<script>
const button = document.getElementById("myButton"); // null!
</script>
<body>
<button id="myButton">Click</button>
</body>
// Good: wait for DOM
<script>
document.addEventListener("DOMContentLoaded", () => {
const button = document.getElementById("myButton");
});
</script>
Mistake 4: Using wrong selector syntax
// Bad: wrong syntax for querySelector
document.querySelector("getElementById"); // Looking for element with tag name!
// Good: use CSS selector syntax
document.querySelector("#myId");
document.querySelector(".myClass");
document.querySelector("div");
Mistake 5: Expecting live updates with querySelectorAll
// querySelectorAll returns static collection
const items = document.querySelectorAll(".item");
console.log(items.length); // 3
// Add new item
const newItem = document.createElement("div");
newItem.className = "item";
document.body.appendChild(newItem);
console.log(items.length); // Still 3! (static snapshot)
// If you need live updates, use getElementsByClassName
const liveItems = document.getElementsByClassName("item");
console.log(liveItems.length); // 4 (live collection)
Working with selected elements
Once you have a reference to an element, the next step is usually to change its content, classes, attributes, or position in the DOM.
Single element
const button = document.querySelector("button");
if (button) {
// Modify it
button.textContent = "New text";
button.style.color = "red";
button.classList.add("active");
}
Multiple elements
// Method 1: Loop with for
const items = document.querySelectorAll(".item");
for (let i = 0; i < items.length; i++) {
items[i].style.color = "blue";
}
// Method 2: forEach (preferred)
document.querySelectorAll(".item").forEach(item => {
item.style.color = "blue";
});
// Method 3: Convert to array
const itemsArray = Array.from(document.querySelectorAll(".item"));
itemsArray.forEach(item => {
item.style.color = "blue";
});
Performance tips
Cache selections
// Bad: querying repeatedly
for (let i = 0; i < 1000; i++) {
const item = document.querySelector(".item");
if (item) {
item.style.color = "red"; // Queries 1000 times!
}
}
// Good: query once
const item = document.querySelector(".item");
if (item) {
for (let i = 0; i < 1000; i++) {
item.style.color = "red";
}
}
Use specific selectors
// Slower: searches entire document
document.querySelector(".item");
// Faster: more specific (if possible)
document.querySelector("#container .item");
Use getElementById for IDs
For simple ID lookups, getElementById is slightly faster:
// Fastest for IDs
document.getElementById("myId");
// Also works, but slightly slower
document.querySelector("#myId");
For broader frontend performance habits, see Performance & Best Practices.
Summary
- Selecting elements means getting references to DOM elements so your JavaScript can work with them.
- Use
querySelector()andquerySelectorAll()as the default modern tools for most cases. - Always remember that single-element selectors can return
null, so check before you use the result.