Skip to content
intermediate Phase 5 · JavaScript Async & DOM

DOM Manipulation

Select, create, modify, and remove DOM elements. Handle events with delegation and bubbling.

1h
0 problems
Topic Progress 0%

Selecting and Reading

Selecting and Reading

document.querySelector accepts full CSS selectors and returns the first match; querySelectorAll returns a static NodeList snapshot, while element.children-style accessors like getElementsByClassName return live collections that mutate as the DOM changes — a classic source of skipped-item bugs when iterating while removing.

Reading textContent, classList, and dataset is cheap; prefer textContent over innerHTML for text you did not author, since assigning to innerHTML parses markup and becomes an XSS sink for any string that originated from a user or API. For attributes, getAttribute/setProperty? Use el.dataset.count = '3' to bind data-* values with automatic camelCase mapping (dataset.count ↔ data-count).

Creating, Mutating, Listening

Creating, Mutating, Listening

const li = document.createElement('li');
li.textContent = item.text;
li.addEventListener('click', onSelect);
list.append(li);          // append/prepend/add before
li.remove();              // detach

Events bubble: a click on a nested span climbs span → li → ul → document. That enables delegation — one listener on the container using e.target.closest('li') handles items that do not exist yet, which is both less memory and correct for re-rendered lists. Listener options: { once: true } auto-removes after firing, { capture: true } listens on the way down, { passive: true } promises not to preventDefault() (faster scrolling), and { signal } ties removal to an AbortController.

Pitfalls and Interview Focus

Pitfalls and Interview Focus

stopPropagation cuts bubbling — overusing it couples components that never heard of each other; prefer delegation and scoped handlers. preventDefault exists for default browser behavior (form submit, link navigation), not for stopping propagation — they are different questions interviewers love to split.

Performance: reading layout properties (offsetHeight, getBoundingClientRect) forces a synchronous reflow; interleave reads before writes or batch mutations with a DocumentFragment so one reflow serves many inserts. Memory: detached nodes stay alive if a closure or listener still references them — remove listeners (AbortController) when tearing down long-lived UI.

Interview: explain bubbling in one sentence, then implement delegation for a dynamically loaded table.

Quiz

1. What's the difference between querySelectorAll and getElementsByClassName?

Question 1 options

2. Why use event delegation on the list container?

Question 2 options

3. Which call forces a synchronous reflow?

Question 3 options

Flashcards

Question

Static vs live collection

Answer

querySelectorAll = snapshot; getElementsBy* = live view that mutates with the DOM.

Question

Event bubbling

Answer

Click on a child climbs ancestors; delegation exploits it with e.target.closest().

Question

preventDefault vs stopPropagation

Answer

Stops browser default behavior vs stops the event traveling up the tree.

Question

passive listener

Answer

Handler guarantees no preventDefault — lets the browser scroll without waiting.

Question

innerHTML danger

Answer

Parses markup → XSS with untrusted strings; use textContent for plain text.

Revision Notes

Key Takeaways

  • 1. Prefer querySelector + textContent; treat innerHTML as an injection risk
  • 2. Delegate clicks on containers — robust for dynamic content, cheaper in memory
  • 3. Read layout in batches; separate reads from writes to avoid reflow storms

Interview Tips

  • • Describe bubbling precisely, then show delegation with closest() in real code
  • • Distinguish preventDefault from stopPropagation — a standard screening split

Cheat Sheet

querySelector(All) static vs getElementsBy* live. textContent over innerHTML (XSS). Delegate with bubbling + e.target.closest(). Options: once/capture/passive/signal. Batch reads before writes.

Continue Learning