← Back to all snippets
JAVASCRIPT

Understanding and Iterating DOM Collections: HTMLCollection vs NodeList

Master the differences between live HTMLCollection and static NodeList in JavaScript, learning efficient methods to convert them to arrays and iterate safely for robust DOM manipulation.

// Assume some elements:
// <div class="item">Item 1</div>
// <div class="item">Item 2</div>
// <span class="item">Item 3</span>

// HTMLCollection (live): Returned by getElementsByClassName, getElementsByTagName
const liveCollection = document.getElementsByClassName('item');
console.log('Initial HTMLCollection size:', liveCollection.length); // e.g., 3

// Add a new element dynamically
const newItem = document.createElement('p');
newItem.className = 'item';
newItem.textContent = 'Item 4 (added)';
document.body.appendChild(newItem);

// HTMLCollection updates automatically because it's 'live'
console.log('Updated HTMLCollection size:', liveCollection.length); // e.g., 4

// To iterate safely with live collections (avoiding issues if elements are added/removed during iteration):
// 1. Convert to Array:
Array.from(liveCollection).forEach(el => {
    console.log('HTMLCollection (Array.from) item:', el.textContent);
});

// NodeList (static for querySelectorAll): Returned by querySelectorAll
const staticNodeList = document.querySelectorAll('.item');
console.log('Initial NodeList size:', staticNodeList.length); // e.g., 4

// Add another element after querySelectorAll was called
const anotherItem = document.createElement('h3');
anotherItem.className = 'item';
anotherItem.textContent = 'Item 5 (added later)';
document.body.appendChild(anotherItem);

// NodeList does NOT update automatically (for querySelectorAll)
console.log('Updated NodeList size (after another add):', staticNodeList.length); // Still 4!

// Iterating NodeList (can use forEach directly or convert to Array)
staticNodeList.forEach(el => {
    console.log('NodeList item (forEach):', el.textContent);
});

// To get an updated static NodeList, you must query again:
const updatedStaticNodeList = document.querySelectorAll('.item');
console.log('Re-queried NodeList size:', updatedStaticNodeList.length); // e.g., 5
How it works: In JavaScript DOM manipulation, `HTMLCollection` (e.g., from `getElementsByClassName`) is a live collection, meaning it automatically updates to reflect changes in the DOM. `NodeList` from `document.querySelectorAll`, however, is static, retaining the elements present at the time it was created. For safe and predictable iteration, especially when modifying the DOM, it's often best practice to convert live collections to a static `Array` using `Array.from()` or the spread operator `[...collection]` before iterating. `NodeList` from `querySelectorAll` can often be iterated directly with `forEach`.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs