Phase 3 · Browser DevelopmentModule 17~44 min read

DOM Fundamentals

Read and change web pages safely by selecting, creating, and updating DOM nodes.

What you'll learn

The DOM is a live object tree representing the document. Professional DOM code owns a small region, creates nodes safely, and updates only what changed.

By the end of this lesson, you'll be able to:

  • Select and inspect DOM nodes
  • Create safe accessible markup
  • Batch updates without unnecessary layout work

Core mental model

Use this decision table as a compact reference. Focus on what each tool means and when it earns its place in production code.

ConceptWhat it meansDecision rule
SelectionquerySelector finds the first CSS-selector matchSelect from the narrowest known root
Safe contenttextContent creates text, not markupUse for untrusted or ordinary text
FragmentDetached container for grouped insertionBuild repeated nodes off-document, then insert once

Professional workflow

Build the behavior in small, observable steps. Each step should leave something you can inspect or test.

  1. Describe the DOM update boundary: inputs, outputs, state, timing, and expected failures.
  2. Implement the smallest correct path with names that expose intent.
  3. Add edge cases and failure handling before introducing abstractions.
  4. Verify behavior with realistic data and one deliberately adversarial example.
  5. Refactor only after the observable behavior is protected.

Make behavior observable

Before optimizing or abstracting, make inputs, outputs, state changes, timing, and failure paths visible. JavaScript becomes much easier to reason about when hidden work is exposed.

Guided code lab

Render a safe lesson list

Create semantic nodes, set textContent, and insert one fragment.

render-lessons.js
const lessons = ["Scope", "Closures", "DOM"];
const list = document.querySelector("#lessons");
const fragment = document.createDocumentFragment();
for (const title of lessons) {
  const item = document.createElement("li");
  item.textContent = title;
  fragment.append(item);
}
list.replaceChildren(fragment);

Separate state from rendering

The render function receives data and owns one DOM region.

counter.js
let count = 0;
const output = document.querySelector("[data-count]");
function render() { output.textContent = String(count); }
document.querySelector("[data-add]").addEventListener("click", () => {
  count += 1;
  render();
});
render();

Production practice

Contract

Keep the DOM update API explicit: accepted state, emitted events, DOM ownership, and cleanup.

Verification

Test with keyboard input, missing elements, repeated initialization, and teardown—not only a mouse happy path.

Operations

Measure user-visible latency and remove listeners, observers, object URLs, or media tracks when the feature ends.

Common failure mode

Assigning untrusted strings to innerHTML can create cross-site scripting; prefer textContent and explicit element creation.

Independent workshop

Build a filterable course-module list from an array of records.

Your finished workshop must include:

  • Semantic list markup
  • Safe text rendering
  • An empty-state message and focused ownership root

Definition of done

Demonstrate the happy path and at least two edge cases, keep responsibilities separated, and add a short note explaining one design choice.

Recap & quick check

Key takeaways

  • The DOM is a tree of live nodes
  • Select from a local root
  • Prefer textContent for text
  • Batch repeated insertions with fragments

Quick check

1. Which property safely inserts plain text?

2. What does querySelector return when no node matches?

3. Why use a DocumentFragment?

Keep the workshop. Later modules deliberately build on these decisions, so each exercise can become part of your final portfolio architecture.