JS DOM Collections
In this page:
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.
Example: NodeList from querySelectorAll
<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.
Example: HTMLCollection from getElementsByClassName/TagName
<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.
Example: Converting Collections to Real Arrays
<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.
Example: Choosing the Right Selection Method
<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.
Example: Common Collection Pitfalls
<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>
- Assuming every DOM collection supports array methods like .map() or .filter() directly -- a NodeList supports forEach, but an HTMLCollection does not support even that without converting it first.
- Not realizing that an HTMLCollection is "live" (automatically reflecting DOM changes), while a NodeList from querySelectorAll is "static" (a fixed snapshot) -- looping over a live collection while modifying the DOM can behave unexpectedly.
- Forgetting to convert a collection to a real array (with Array.from() or the spread operator) before using array methods that neither collection type supports natively.
- querySelectorAll() returns a static NodeList, which supports forEach() but not other array methods directly.
- getElementsByClassName() and getElementsByTagName() return a live HTMLCollection, which does not support forEach() at all.
- Array.from(collection) converts any DOM collection into a real array, unlocking the full set of array methods.
NodeList and HTMLCollection have both been supported in every browser since the earliest DOM implementations.
Chapter Quiz — Complete all 26 topics to unlock
0/26 topics done
Complete these topics first:
- JS Dates
- JS Math
- JS Conditionals
- JS Switch
- JS Loop For
- JS Loop While
- JS Iterables
- JS Sets
- JS Maps
- JS typeof
- JS Type Conversion
- JS Destructuring
- JS Arrow Functions
- JS Classes
- JS Modules
- JS Promises
- JS Async/Await
- JS DOM
- JS DOM Methods
- JS Events Advanced
- JS DOM Navigation
- JS DOM Collections
- JS Async Callbacks
- JS Async Parallel
- JS Date Set
- JS Set Logic