Skip to main content

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).

tip

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() and querySelectorAll() as the default modern tools for most cases.
  • Always remember that single-element selectors can return null, so check before you use the result.

Next up​