JavaScript > DOM Manipulation > Selecting Elements > querySelectorAll()

Selecting Multiple Elements with querySelectorAll()

This code snippet demonstrates how to use querySelectorAll() to select multiple elements based on a CSS selector. It covers basic usage, different selector types, and iterating over the results.

Basic Usage

This snippet selects all elements with the class 'my-class' and stores them in a NodeList called 'elements'. The console.log then displays the NodeList in the console.

const elements = document.querySelectorAll('.my-class');
console.log(elements);

Explanation of querySelectorAll()

querySelectorAll() is a method of the Document interface that returns a static (not live) NodeList representing a list of the document's elements that match the specified group of selectors. It accepts a CSS selector string as an argument. Unlike getElementsByClassName or getElementsByTagName, querySelectorAll returns a NodeList, not a HTMLCollection.

Iterating over the NodeList

This snippet iterates over the NodeList returned by querySelectorAll() using the forEach method. For each element found, it changes the text color to red.

const elements = document.querySelectorAll('.my-class');

elements.forEach(element => {
  element.style.color = 'red';
});

Selecting Elements by Tag Name

This snippet selects all paragraph elements (<p> tags) and increases their font size to 18px.

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

paragraphs.forEach(paragraph => {
  paragraph.style.fontSize = '18px';
});

Selecting Elements by ID

This snippet selects the element with the ID 'my-id'. Note that although IDs should be unique, querySelectorAll still returns a NodeList. Therefore, we need to check if the NodeList has any elements and access the first element (element[0]) to modify it. The if statement is crucial because if no element with the ID is found, accessing element[0] will throw an error. Because an ID should be unique the nodelist length should be 0 or 1.

const element = document.querySelectorAll('#my-id');

if (element.length > 0) {
  element[0].style.fontWeight = 'bold';
}

Selecting Elements by Attribute

This snippet selects all elements with the attribute data-type set to 'highlight' and changes their background color to yellow. Notice the escaping of the double quotes within the selector string using backslashes.

const elements = document.querySelectorAll('[data-type="highlight"]');

elements.forEach(element => {
  element.style.backgroundColor = 'yellow';
});

Concepts Behind the Snippet

querySelectorAll() leverages CSS selectors to identify elements within the DOM. Understanding CSS selectors (e.g., class selectors, ID selectors, attribute selectors, pseudo-classes) is crucial for effectively using querySelectorAll(). The returned NodeList is a static snapshot; changes to the DOM after the query won't be reflected in the NodeList.

Real-Life Use Case

Imagine a scenario where you have a web page with multiple product listings, each marked with a class. You can use querySelectorAll() to select all product listings and apply a uniform styling (e.g., adding a border, changing the font, or attaching an event listener for adding to cart). Another usecase is validation: imagine that each of your fields have a dedicated attribute, you can select all of them with a dedicated CSS selector and start the validation process.

Best Practices

  • Specificity: Use specific CSS selectors to avoid unintended selections.
  • Performance: While generally performant, avoid overly complex selectors, especially on large documents. Test performance if needed.
  • Caching: If you need to perform the same selection multiple times, store the NodeList in a variable to avoid repeated DOM traversals.

Interview Tip

Be prepared to discuss the differences between querySelectorAll(), getElementsByClassName(), and getElementsByTagName(). Understand the return types (NodeList vs. HTMLCollection) and whether they are live or static. Also, be ready to explain how CSS selectors work.

When to Use Them

Use querySelectorAll() when you need to select multiple elements based on complex criteria defined by CSS selectors. It is particularly useful when you need to target elements with specific attributes, nested elements, or elements matching a combination of classes and IDs.

Memory Footprint

querySelectorAll creates a static NodeList. While the memory footprint depends on the number of elements selected, storing a large NodeList can consume memory. Be mindful of this when working with large documents or complex selectors.

Alternatives

  • getElementsByClassName(): Selects elements by class name (returns a live HTMLCollection).
  • getElementsByTagName(): Selects elements by tag name (returns a live HTMLCollection).
  • getElementById(): Selects a single element by ID (returns a single element).
  • querySelector(): Selects the first element that matches a CSS selector.

Pros

  • Versatile: Supports a wide range of CSS selectors.
  • Consistent: Returns a NodeList, regardless of the number of elements found.
  • Widely Supported: Well-supported across modern browsers.

Cons

  • Static NodeList: Changes to the DOM after the initial selection are not reflected in the NodeList.
  • Performance: Can be slower than getElementsByClassName() or getElementsByTagName() for simple selections, especially on older browsers or with very complex selectors.

FAQ

  • What is the difference between NodeList and HTMLCollection?

    NodeList can contain any type of node, including elements, text nodes, and attributes. HTMLCollection contains only HTML elements. Also, NodeList returned by querySelectorAll is static, while HTMLCollection returned by getElementsByClassName and getElementsByTagName is live (updates automatically when the DOM changes).
  • Does querySelectorAll() return a live NodeList?

    No, querySelectorAll() returns a static NodeList. This means that if the DOM changes after you call querySelectorAll(), the NodeList will not be updated.
  • Can I use querySelectorAll() inside another element to search within that element's children?

    Yes, you can call querySelectorAll() on a specific element to search within its descendants. For example: const myDiv = document.getElementById('myDiv'); const paragraphs = myDiv.querySelectorAll('p'); This will select all paragraph elements that are descendants of the element with the ID 'myDiv'.