DOM Collections
DOM queries return one of two collection types. They look like arrays but each has subtle differences worth knowing.
HTMLCollection vs. NodeList
| HTMLCollection | NodeList | |
|---|---|---|
| Returned by | el.children, document.forms, getElementsByTagName, getElementsByClassName | querySelectorAll, childNodes |
| Contains | Elements only | Any nodes |
| Live or static | Live — updates as DOM changes | Usually static (childNodes is live) |
Supports forEach | No | Yes |
| Spread to array | [...collection] | [...nodeList] |
Working with both
JS
// Access by index
list.children[0];
// Iterate — forEach only works on NodeList
document.querySelectorAll("li").forEach(li => li.classList.add("ready"));
// Convert to an array for full Array methods
[...list.children].map(li => li.textContent);
Array.from(list.children, li => li.textContent); // map in one go
Live vs. static — why it matters
JS
const live = list.children; // HTMLCollection — live
const snapped = document.querySelectorAll("li"); // NodeList — static
list.append(document.createElement("li"));
live.length; // grew by 1
snapped.length; // unchanged
Tip: Default to
querySelectorAll. The static snapshot prevents loop bugs that pop up when you modify the DOM mid-iteration.Example
Example
<!DOCTYPE html>
<html>
<body>
<p id="out"></p>
<script>
document.getElementById("out").textContent = "Hello from DOM Collections!";
</script>
</body>
</html>
Try it Yourself »
Exercise
Turn a NodeList into a real array using spread.
const items =
document.querySelectorAll('li')];
Four characters that open an array and unpack.
Discussion
Loading…