Course outline · 0% complete

0/30 lessons0%

Course overview →

Creating elements from data

lesson 8-4 · ~10 min · 27/30

Pages built from arrays

Real interfaces are rarely written by hand element-by-element: search results, chat messages, and product lists arrive as arrays of data, and the page must manufacture one element per entry. Every feed you have ever scrolled works this way. The DOM gives you three operations for it:

const li = document.createElement("li"); // 1. make a detached node
li.textContent = "Ada";                  // 2. fill it in
list.append(li);                         // 3. attach it into the tree

A created element is invisible until append places it inside a node that is already on the page. The reverse operation is just as short: element.remove() detaches it again.

The full loop, the shape you will write hundreds of times:

const names = ["Ada", "Grace", "Linus"];
const list = document.querySelector("#list");

for (const name of names) {
  const li = document.createElement("li");
  li.textContent = name;
  list.append(li);
}

textContent vs innerHTML — a security line

There is a tempting shortcut: element.innerHTML = "<li>Ada</li>" parses a string as HTML and builds the nodes for you. The danger appears the moment any part of that string came from a user. If someone sets their display name to <img src=x onerror="...">, innerHTML will happily build that element and run the attacker's code in every visitor's browser. This attack is called XSS (cross-site scripting), and it is one of the most common real-world web vulnerabilities.

textContent is immune: it treats the string as plain text, so < arrives on screen as a literal < character — the browser performs the lesson 2-4 entity escaping for you.

The working rule, enforced in real code reviews:

  • Data (anything typed by a user or fetched from a server) goes in via textContent.
  • innerHTML only ever receives markup you wrote yourself, never data.

Code exercise · javascript

Your turn: build the escaper that makes untrusted text safe to place inside markup, exactly what textContent does internally. Write escapeHtml(text) that replaces & with &amp;, < with &lt;, and > with &gt;.

Render the roster. In the JS pane: select the #roster ul, then loop over the names array, and for each name create an li with createElement, set its textContent, and append it to the list. Add a fourth name to the array and watch the page follow the data.

Quiz

A user's display name arrives from your server and must be shown inside a card. Which assignment is safe?