← Back to JavaScript Course | Chapter 4: Modern JS, Async & DOM | Lesson 22 of 26

JS DOM Collections

Several DOM methods return a collection of multiple elements at once -- but not all collections behave identically. NodeList (from querySelectorAll) and HTMLCollection (from getElementsByClassName/TagName) look similar but differ in whether they update automatically and which array methods they support directly.
Syntax
javascript
document.getElementsByTagName("tag");
document.getElementsByClassName("class");
document.querySelectorAll("selector");
document.forms;

NodeList from querySelectorAll

document.querySelectorAll() returns a NodeList -- a static snapshot of matching elements at the moment the query ran, which does not automatically update if the DOM changes afterward, and which directly supports the forEach() method for iteration.

Note: Use querySelectorAll() as your default way to select multiple elements, since its resulting NodeList's forEach() support makes iteration straightforward.
Warning: A NodeList's static nature means it will not reflect new elements added to the page after the query ran -- re-run the query if you need an up-to-date collection.

उदाहरण: NodeList from querySelectorAll

javascript
<p class="item">A</p><p class="item">B</p>
<script>
  const list = document.querySelectorAll(".item"); // static NodeList
  list.forEach(el => console.log(el.textContent));
</script>

HTMLCollection from getElementsByClassName/TagName

document.getElementsByClassName() and getElementsByTagName() return an HTMLCollection -- a "live" collection that automatically updates to reflect DOM changes as they happen, but which does not support forEach() directly, requiring conversion to an array first for most iteration needs.

Note: Convert an HTMLCollection to a real array with Array.from() before using array methods like forEach, map, or filter on it.
Warning: Looping over a live HTMLCollection with a plain for loop while simultaneously adding or removing matching elements can produce confusing results, since the collection's length changes mid-loop.

उदाहरण: HTMLCollection from getElementsByClassName/TagName

javascript
<p class="item">A</p>
<script>
  const collection = document.getElementsByClassName("item"); // live HTMLCollection
  console.log(collection.length);
</script>

Converting Collections to Real Arrays

Array.from(collection) (or the spread syntax [...collection]) converts either a NodeList or an HTMLCollection into a genuine JavaScript array, unlocking the full array method set -- map, filter, reduce, and more -- that neither DOM collection type fully supports on its own.

Note: Convert to a real array with Array.from() the moment you need anything beyond basic iteration, like transforming or filtering the collection.
Warning: Converting a live HTMLCollection to an array captures a fixed snapshot at that moment -- the resulting array will not continue to update the way the original live collection would have.

उदाहरण: Converting Collections to Real Arrays

javascript
<p class="item">A</p><p class="item">B</p>
<script>
  // Declare the constant `collection`, set to `document.getElementsByClassName("item")`
  const collection = document.getElementsByClassName("item");
  // Declare the constant `arr`, set to `Array.from(collection)`
  const arr = Array.from(collection);
  // Print `arr.map(el => el.textContent)` to the console
  console.log(arr.map(el => el.textContent));
</script>

Choosing the Right Selection Method

querySelectorAll() with its flexible CSS-selector syntax and forEach-ready NodeList is the more modern, generally preferred default; getElementsByClassName/TagName remain useful specifically when you want a live, auto-updating collection that tracks DOM changes automatically.

Note: Default to querySelectorAll() for most element selection needs; reach for getElementsBy* specifically when you deliberately want a live collection.
Warning: Choosing a live HTMLCollection when you actually wanted a fixed snapshot (or vice versa) can introduce subtle bugs that only appear once the DOM changes after the initial selection.

उदाहरण: Choosing the Right Selection Method

javascript
<p class="item">A</p>
<script>
  console.log(document.querySelectorAll(".item")); // modern default
  console.log(document.getElementsByClassName("item")); // live collection
</script>

Common Collection Pitfalls

Two frequent mistakes: forgetting a collection might be empty (checking .length before assuming an element exists), and modifying the DOM while iterating a live HTMLCollection with a plain for loop, which can cause elements to be skipped or visited twice as the collection's length shifts mid-loop.

Note: When removing elements from a live collection while iterating it, loop backward (from the end toward the start) or convert to a static array first, to avoid the shifting-length problem.
Warning: Removing elements from a live HTMLCollection while iterating it forward with a standard for loop is a classic bug -- indices shift as elements are removed, causing some to be skipped.

उदाहरण: Common Collection Pitfalls

javascript
<p class="item">A</p>
<script>
  const items = document.querySelectorAll(".missing");
  if (items.length === 0) console.log("No matching elements found"); // check length first
</script>
Live Example
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.