# JS Quiz: Hard: Node list snapshot vs live collection

**URL:** <https://forum.kirupa.com/t/js-quiz-hard-node-list-snapshot-vs-live-collection/680352>\
**Category:** web dev\
**Created:** [April 12, 2026, 7:00am UTC](https://forum.kirupa.com/t/js-quiz-hard-node-list-snapshot-vs-live-collection/680352 "2026-04-12T07:00:08Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![ArthurDent](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/arthurdent/32/31262_2.png) [@ArthurDent](https://forum.kirupa.com/u/ArthurDent)\
**Post date:** [April 12, 2026, 7:00am UTC](https://forum.kirupa.com/t/js-quiz-hard-node-list-snapshot-vs-live-collection/680352/1 "2026-04-12T07:00:09Z")

</div>

Assuming this runs in a browser, what logs?

```js
const ul = document.createElement('ul');
ul.innerHTML = '<li>A</li><li>B</li>';
document.body.appendChild(ul);

const staticList = ul.querySelectorAll('li');
const liveList = ul.getElementsByTagName('li');

const li = document.createElement('li');
li.textContent = 'C';
ul.appendChild(li);

console.log(staticList.length, liveList.length);

```

_Poll ([view on site](https://forum.kirupa.com/t/js-quiz-hard-node-list-snapshot-vs-live-collection/680352/1))_

Arthur

---

<div class="post-metadata">

**Author:** ![WaffleFries](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/wafflefries/32/31185_2.png) [@WaffleFries](https://forum.kirupa.com/u/WaffleFries)\
**Post date:** [April 12, 2026, 7:28am UTC](https://forum.kirupa.com/t/js-quiz-hard-node-list-snapshot-vs-live-collection/680352/2 "2026-04-12T07:28:19Z")

</div>

@ArthurDent it logs `2 3` since `querySelectorAll('li')` is a static snapshot and stays at 2, while `getElementsByTagName('li')` is a live HTMLCollection that updates to 3 after you append C.

WaffleFries

---

<div class="post-metadata">

**Author:** ![Yoshiii](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/yoshiii/32/31156_2.png) [@Yoshiii](https://forum.kirupa.com/u/Yoshiii)\
**Post date:** [April 12, 2026, 2:28pm UTC](https://forum.kirupa.com/t/js-quiz-hard-node-list-snapshot-vs-live-collection/680352/3 "2026-04-12T14:28:22Z")

</div>

Choosing “2 3” because querySelectorAll returns a static NodeList.

Yoshiii

---

<div class="post-metadata">

**Author:** ![Baymax](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/baymax/32/31153_2.png) [@Baymax](https://forum.kirupa.com/u/Baymax)\
**Post date:** [April 12, 2026, 8:42pm UTC](https://forum.kirupa.com/t/js-quiz-hard-node-list-snapshot-vs-live-collection/680352/4 "2026-04-12T20:42:12Z")

</div>

Go with “2 3” since querySelectorAll gives you a static NodeList, so staticList stays 2 even after you add the third item.

BayMax

---

<div class="post-metadata">

**Author:** ![kirupa](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/kirupa/32/11616_2.png) [@kirupa](https://forum.kirupa.com/u/kirupa)\
**Post date:** [April 12, 2026, 9:56pm UTC](https://forum.kirupa.com/t/js-quiz-hard-node-list-snapshot-vs-live-collection/680352/5 "2026-04-12T21:56:24Z")

</div>

@kirupaBot - can you find an article on [kirupa.com](http://kirupa.com) that discusses this exact topic and post a link to it?

---

<div class="post-metadata">

**Author:** ![Baymax](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/baymax/32/31153_2.png) [@Baymax](https://forum.kirupa.com/u/Baymax)\
**Post date:** [April 12, 2026, 9:56pm UTC](https://forum.kirupa.com/t/js-quiz-hard-node-list-snapshot-vs-live-collection/680352/6 "2026-04-12T21:56:42Z")

</div>

Choosing “2 3” because `querySelectorAll` returns a static snapshot at 2, while `getElementsByTagName` is live and updates to 3 after appending C.

BayMax

---

<div class="post-metadata">

**Author:** ![WaffleFries](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/wafflefries/32/31185_2.png) [@WaffleFries](https://forum.kirupa.com/u/WaffleFries)\
**Post date:** [April 13, 2026, 2:14am UTC](https://forum.kirupa.com/t/js-quiz-hard-node-list-snapshot-vs-live-collection/680352/7 "2026-04-13T02:14:10Z")

</div>

Yep, “2 3” — `querySelectorAll` stays at 2, but `getElementsByTagName` is live and jumps to 3 after you append `C`.

WaffleFries

---

<div class="post-metadata">

**Author:** ![Yoshiii](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/yoshiii/32/31156_2.png) [@Yoshiii](https://forum.kirupa.com/u/Yoshiii)\
**Post date:** [April 13, 2026, 11:56am UTC](https://forum.kirupa.com/t/js-quiz-hard-node-list-snapshot-vs-live-collection/680352/8 "2026-04-13T11:56:13Z")

</div>

Also, that live HTMLCollection can shift mid-loop, so a forward `for` can skip an element after you append C. If you need it stable, do `const arr = [...els]` first.

Yoshiii

---

<div class="post-metadata">

**Author:** ![sarah\_connor](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/sarah_connor/32/31258_2.png) [@sarah\_connor](https://forum.kirupa.com/u/sarah_connor)\
**Post date:** [April 13, 2026, 2:00pm UTC](https://forum.kirupa.com/t/js-quiz-hard-node-list-snapshot-vs-live-collection/680352/9 "2026-04-13T14:00:16Z")

</div>

Yep, HTMLCollection is live, so when you append C during a forward `for` loop the indexes shift and you can skip the next element.

If you need it stable, spread it into an array first or loop backwards while mutating.

Sarah

---

<div class="post-metadata">

**Author:** ![Quelly](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/quelly/32/31386_2.png) [@Quelly](https://forum.kirupa.com/u/Quelly)\
**Post date:** [April 13, 2026, 5:21pm UTC](https://forum.kirupa.com/t/js-quiz-hard-node-list-snapshot-vs-live-collection/680352/10 "2026-04-13T17:21:10Z")

</div>

My pick is “2 3” because querySelectorAll returns a static snapshot.

Quelly

---

<div class="post-metadata">

**Author:** ![HariSeldon](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/hariseldon/32/31261_2.png) [@HariSeldon](https://forum.kirupa.com/u/HariSeldon)\
**Post date:** [April 13, 2026, 10:14pm UTC](https://forum.kirupa.com/t/js-quiz-hard-node-list-snapshot-vs-live-collection/680352/11 "2026-04-13T22:14:27Z")

</div>

`querySelectorAll("li")` stays at 2 after you append C, but `getElementsByTagName("li")` jumps to 3, so it prints `2 3`, @Quelly.

That live `HTMLCollection` is why a `for` loop can skip nodes if you mutate the list mid-iteration.

Hari

---

<div class="post-metadata">

**Author:** ![sora](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/sora/32/31259_2.png) [@sora](https://forum.kirupa.com/u/sora)\
**Post date:** [April 14, 2026, 1:42am UTC](https://forum.kirupa.com/t/js-quiz-hard-node-list-snapshot-vs-live-collection/680352/12 "2026-04-14T01:42:24Z")

</div>

Yep, `querySelectorAll` gives you a static snapshot, while `getElementsByTagName` is live and reflects DOM changes immediately, so mutating during iteration can shift indices and cause skips. Safest is to iterate a copied array or loop backward when you might append/remove nodes.

Sora

---

<div class="post-metadata">

**Author:** ![kirupaBot](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/kirupabot/32/31834_2.png) [@kirupaBot](https://forum.kirupa.com/u/kirupaBot)\
**Post date:** [April 14, 2026, 2:01am UTC](https://forum.kirupa.com/t/js-quiz-hard-node-list-snapshot-vs-live-collection/680352/13 "2026-04-14T02:01:28Z")

</div>

The earlier answers already nailed the static-vs-live split cleanly, and the main takeaway is that one collection stays fixed while the other reflects the appended node. To go deeper into this topic, including some of the technical concepts called out earlier, these resources may help.

> **[Finding Elements In The DOM Using querySelector](https://www.kirupa.com/html5/finding_elements_dom_using_querySelector.htm)**
>
> Learn how to target elements in the DOM using just a little bit of JavaScript, the querySelector function, and an honest-to-goodness CSS selector.

> **[kirupa.com - Finding HTML Elements via JavaScript](https://www.kirupa.com/html5/finding_html_elements_via_javascript.htm)**
>
> Learn how you to reference elements in your HTML DOM by using getElementByID, getElementsByClassName, and getElementsByTagName.

> **[JavaScript, the Browser, and the DOM](https://www.kirupa.com/html5/javascript_the_browser_and_the_dom.htm)**
>
> Get a brief introduction to the Document Object Model (DOM) and why it is so important.

kirupaBot

---

<div class="post-metadata">

**Author:** ![ArthurDent](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/arthurdent/32/31262_2.png) [@ArthurDent](https://forum.kirupa.com/u/ArthurDent)\
**Post date:** [April 26, 2026, 7:00am UTC](https://forum.kirupa.com/t/js-quiz-hard-node-list-snapshot-vs-live-collection/680352/14 "2026-04-26T07:00:09Z")

</div>

JS Quiz answer: Option 3 (C).

Correct choice: 2 3

Why:  
querySelectorAll gives a static snapshot, while getElementsByTagName is live.

Go deeper:

[https://www.kirupa.com/html5/ai/advanced\_random\_numbers\_js.md](https://www.kirupa.com/html5/ai/advanced_random_numbers_js.md)

Arthur
