JavaScript querySelector() and querySelectorAll()

JavaScript provides several methods to select HTML elements and interact with them. Two of the most commonly used methods are querySelector() and querySelectorAll().

These methods allow you to select HTML elements using CSS selectors, such as element names, class names, IDs, and attribute selectors. Once an element is selected, you can change its text, update its styles, respond to user interactions, or modify its content.

In this tutorial, you will learn how querySelector() and querySelectorAll() work, how to use them with CSS selectors, and what makes them different.

What Is querySelector() in JavaScript?

The querySelector() method selects and returns the first element inside a specified parent that matches a CSS selector.

If multiple elements match the selector, querySelector() returns only the first matching element. If no element matches, it returns null.

Syntax of querySelector()

document.querySelector("CSS selector");

Here, document represents the HTML document, and the CSS selector specifies the element you want to find.

You can use querySelector() with element selectors, class selectors, ID selectors, and other valid CSS selectors.

Selecting an Element by Tag Name

Suppose your HTML contains the following paragraph elements:

<p>First paragraph</p>
<p>Second paragraph</p>
<p>Third paragraph</p>

You can select the first paragraph using JavaScript:

const paragraph = document.querySelector("p");

console.log(paragraph.textContent);

Output:

First paragraph

The selector "p" matches paragraph elements. Because querySelector() returns only the first match, the second and third paragraphs are not selected by this call.

Selecting an Element by Class Name

To select an element by its class, use a dot (.) followed by the class name.

HTML:

<p class="message">Hello, JavaScript!</p>
<p class="message">Welcome to Web4Learners!</p>

JavaScript:

const element = document.querySelector(".message");

console.log(element.textContent);

Output:

Hello, JavaScript!

The selector .message matches elements with the class message. Only the first matching element is returned.

Selecting an Element by ID

To select an element by its ID, use the hash symbol (#) followed by the ID name.

HTML:

<h1 id="heading">JavaScript Tutorial</h1>

JavaScript:

const heading = document.querySelector("#heading");

console.log(heading.textContent);

Output:

JavaScript Tutorial

Because IDs are intended to identify a single element within a document, querySelector("#heading") is a common way to select an element by ID.

Changing an Element Using querySelector()

After selecting an element, you can update its content or styles.

HTML:

<p class="message">Original message</p>

JavaScript:

const message = document.querySelector(".message");

message.textContent = "Message updated successfully!";
message.style.color = "blue";

The paragraph’s text changes to Message updated successfully!, and its text color becomes blue.

This demonstrates how selecting an element allows JavaScript to modify a webpage dynamically.

What Is querySelectorAll() in JavaScript?

The querySelectorAll() method selects all elements inside a specified parent that match a CSS selector.

It returns a static NodeList, which is a collection of matching nodes. If no elements match, it returns an empty NodeList.

Unlike querySelector(), this method does not stop after finding the first matching element.

Syntax of querySelectorAll()

document.querySelectorAll("CSS selector");

The selector can be an element name, class, ID, attribute selector, or another valid CSS selector.

Selecting All Elements by Tag Name

HTML:

<p>First paragraph</p>
<p>Second paragraph</p>
<p>Third paragraph</p>

JavaScript:

const paragraphs = document.querySelectorAll("p");

console.log(paragraphs.length);

Output:

3

The selector "p" matches all three paragraph elements. The returned NodeList contains three elements, and its length property reports the number of matches.

Selecting All Elements by Class Name

HTML:

<p class="message">First message</p>
<p class="message">Second message</p>
<p class="message">Third message</p>

JavaScript:

const messages = document.querySelectorAll(".message");

messages.forEach(function (message) {
  console.log(message.textContent);
});

Output:

First message
Second message
Third message

The selector .message matches every element with that class. The forEach() method then processes each element in the NodeList.

Selecting Elements by ID

HTML IDs should be unique within a document, but querySelectorAll() can still be used with an ID selector.

<h2 id="title">JavaScript Basics</h2>

JavaScript:

const titles = document.querySelectorAll("#title");

console.log(titles.length);

Output:

1

Because the document contains one matching element, the NodeList has a length of 1. If no element matched, the length would be 0.

Changing Multiple Elements Using querySelectorAll()

You can use querySelectorAll() to apply the same change to multiple elements.

HTML:

<p class="highlight">First paragraph</p>
<p class="highlight">Second paragraph</p>
<p class="highlight">Third paragraph</p>

JavaScript:

const paragraphs = document.querySelectorAll(".highlight");

paragraphs.forEach(function (paragraph) {
  paragraph.style.color = "blue";
});

All three paragraphs will have blue text.

This technique is useful when you want to update multiple elements without selecting each one separately.

Using CSS Selectors with querySelector() and querySelectorAll()

Both methods support CSS selectors. This allows you to select elements based on their names, classes, IDs, attributes, and relationships with other elements.

Selecting Descendant Elements

HTML:

<div class="container">
  <p>Paragraph inside container</p>
</div>

<p>Paragraph outside container</p>

JavaScript:

const paragraph = document.querySelector(".container p");

console.log(paragraph.textContent);

Output:

Paragraph inside container

The selector .container p selects a paragraph that is a descendant of an element with the class container.

Selecting Elements by Attribute

HTML:

<input type="text" name="username">
<input type="email" name="email">

JavaScript:

const emailInput = document.querySelector('input[type="email"]');

console.log(emailInput.name);

Output:

email

The attribute selector input[type="email"] selects an input element whose type attribute is email.

Selecting Multiple Classes

HTML:

<p class="message active">Active message</p>
<p class="message">Regular message</p>

JavaScript:

const activeMessage = document.querySelector(".message.active");

console.log(activeMessage.textContent);

Output:

Active message

The selector .message.active matches an element that has both the message and active classes.

Using Multiple Selectors

You can separate selectors with commas to match elements belonging to different selector groups.

HTML:

<h2>JavaScript</h2>
<p>Learn programming</p>
<button>Start Learning</button>

JavaScript:

const elements = document.querySelectorAll("h2, p, button");

console.log(elements.length);

Output:

3

The method returns all matching elements in document order.

Difference Between querySelector() and querySelectorAll()

Both methods use CSS selectors, but they return different results.

FeaturequerySelector()querySelectorAll()
PurposeSelects the first matching elementSelects all matching elements
Return valueAn element or nullA static NodeList
Multiple matchesReturns only the firstReturns all matches
No matchesReturns nullReturns an empty NodeList
IterationNot needed for a single elementCommonly used with forEach()
length propertyNot available on the element itself as a match countAvailable on the NodeList

Consider the following HTML:

<p class="item">Item 1</p>
<p class="item">Item 2</p>
<p class="item">Item 3</p>

Using querySelector():

const item = document.querySelector(".item");

console.log(item.textContent);

Output:

Item 1

Using querySelectorAll():

const items = document.querySelectorAll(".item");

console.log(items.length);

Output:

3

Use querySelector() when you need the first matching element. Use querySelectorAll() when you need to work with every matching element.

What Is a Static NodeList?

The querySelectorAll() method returns a static NodeList. This means the collection does not automatically update when matching elements are added to or removed from the document.

For example:

<p class="item">First item</p>
<p class="item">Second item</p>
const items = document.querySelectorAll(".item");

console.log(items.length);

const newItem = document.createElement("p");
newItem.className = "item";
newItem.textContent = "Third item";

document.body.appendChild(newItem);

console.log(items.length);
console.log(document.querySelectorAll(".item").length);

Output:

2
2
3

The first NodeList still contains the two elements selected initially. A new call to querySelectorAll() returns a new NodeList containing all three matching elements.

This is an important difference between static NodeLists and certain live DOM collections, such as those returned by getElementsByClassName().

Handling Elements That Do Not Exist

Sometimes, a selector does not match any element. It is important to check the result before attempting to access element properties.

Handling querySelector()

const heading = document.querySelector("#missingHeading");

if (heading) {
  heading.textContent = "Heading found";
} else {
  console.log("Heading not found");
}

Output:

Heading not found

Because no element matches #missingHeading, querySelector() returns null. The condition prevents JavaScript from trying to update a nonexistent element.

Handling querySelectorAll()

const items = document.querySelectorAll(".missingItem");

console.log(items.length);

items.forEach(function (item) {
  console.log(item.textContent);
});

Output:

0

When no elements match, querySelectorAll() returns an empty NodeList. Calling forEach() on it is valid, but the callback does not run.

Important: If a CSS selector string is invalid, either method can throw a SyntaxError. A valid selector that simply matches nothing does not throw this error.

Common Mistakes When Using querySelector() and querySelectorAll()

Forgetting the Dot Before a Class Name

Incorrect:

document.querySelector("message");

This searches for an HTML element named message.

Correct:

document.querySelector(".message");

The dot indicates a class selector.

Forgetting the Hash Before an ID

Incorrect:

document.querySelector("heading");

Correct:

document.querySelector("#heading");

The hash symbol identifies an ID selector.

Treating querySelectorAll() Like a Single Element

Incorrect:

const items = document.querySelectorAll(".item");

items.style.color = "blue";

The result is a NodeList, not an individual element. The style property belongs to each matching element.

Correct:

const items = document.querySelectorAll(".item");

items.forEach(function (item) {
  item.style.color = "blue";
});

Using an Element Before It Exists

If JavaScript runs before the target HTML element has been parsed, querySelector() may return null.

You can place the script after the relevant HTML or use an appropriate event such as DOMContentLoaded when necessary.

Frequently Asked Questions

What is the difference between querySelector() and querySelectorAll()?

querySelector() returns the first matching element, while querySelectorAll() returns a static NodeList containing all matching elements.

Can querySelector() select an element by class?

Yes. Use a dot followed by the class name, such as document.querySelector(".message").

Can querySelectorAll() select elements by ID?

Yes. You can use an ID selector such as document.querySelectorAll("#heading"). If the ID is unique and the element exists, the NodeList will usually contain one element.

What happens when querySelector() finds no element?

It returns null. Check the result before accessing properties such as textContent or style.

What does querySelectorAll() return when no elements match?

It returns an empty static NodeList with a length of 0.

Can I use CSS selectors with both methods?

Yes. Both methods accept valid CSS selector strings, including element, class, ID, attribute, descendant, child, and grouped selectors.

Does querySelectorAll() return a live collection?

No. It returns a static NodeList that does not automatically update when the DOM changes. Call querySelectorAll() again to get a collection reflecting the current document.

Conclusion

The querySelector() and querySelectorAll() methods are essential tools for selecting HTML elements with JavaScript.

Use querySelector() to select the first matching element and querySelectorAll() to select all matching elements. Both methods support CSS selectors, making them useful for updating content, changing styles, handling events, and building interactive webpages.

Understanding these methods will help you work with the DOM more effectively and create dynamic web applications.