The live-list bug, and the fix
Each removal shrank the live list, so the items shifted down while i moved up: paragraphs 2 and 4 were skipped. Looping over a static querySelectorAll snapshot removes every one.
Before you can change an element you must find it: getElementById finds one by id, querySelector and querySelectorAll find elements with any CSS selector, and closest searches upwards; knowing which return live collections and which return null prevents most DOM bugs.
Change the code and press Run (Ctrl+Enter). Predict what will happen first, then break it on purpose and read what changes. Your edits are saved and match the lesson page.
Ready for more? This phase has 5 hands-on exercises with automatic checks.
Practice questions
Write the code in the editor, run it, then open the model answer to compare.
Given a list of products where some have class sale, log how many are on sale and the text of the first one, using one selector per lookup.
Given <button class="remove"> inside <li class="task" data-id="7">, write a function taskIdOf(button) that returns the task's data-id attribute using closest.
Turn all .price elements into an array of numbers and log their total.
Explain it without notes
Compare getElementById, querySelector and querySelectorAll: arguments, return values and what happens when nothing matches.
What is the difference between a NodeList and an HTMLCollection, and between live and static lists?
What does element.closest(selector) do, and when would you use it?
Why can removing classes inside a loop over getElementsByClassName skip elements? How do you avoid it?
Preview
Console
Nothing logged yet.Expected console output
Still new after the buggy loop: 2
Still new after the fix: 0