Skip to content
Topic 4 of 5
Theory

Creating Elements and Lists

A page from data

In real applications a list of products, messages or tasks isn't written in HTML in advance — it arrives as an array of data, and JavaScript builds elements from it by itself. You added an item to the cart — the array has one more object, and a new row appeared on the page.

createElement

A new element is created "in the air" and isn't visible yet:

const li = document.createElement("li");   // <li></li>
li.textContent = "Buy bread";
li.classList.add("task");
li.dataset.id = "7";

To make it appear, you need to insert it into an element that is already on the page.

Where to insert

const list = document.querySelector("#todo");

list.append(li);        // at the end of list
list.prepend(li);       // at the beginning of list
list.before(li);        // before list (as a sibling)
list.after(li);         // after list
list.append(a, b, "text");   // several at once, strings become text

One element can't be in two places: if you insert an already inserted li again, it moves to the new place.

Removing and clearing

li.remove();                 // remove the element from the page
list.replaceChildren();      // remove all children
list.innerHTML = "";         // the same thing, also very common

Rendering a list from an array

The most common technique: a render function that clears the container and builds it again from the array. The data changed — call render() again.

const tasks = ["Wash the dishes", "Do homework", "Go for a walk"];

function render() {
  const list = document.querySelector("#todo");
  list.replaceChildren();
  for (const text of tasks) {
    const li = document.createElement("li");
    li.textContent = text;
    list.append(li);
  }
}

render();
tasks.push("Read a book");
render();

Rebuilding everything from scratch is simpler than finding and changing individual items, and for small lists it's fast. This very idea — "the interface is a function of the data" — is later perfected by React and Vue.

Why not a string through innerHTML

You can build the markup as a string:

list.innerHTML = tasks.map((t) => `<li>${t}</li>`).join("");

It's short, but dangerous: if the text came from a user and contains tags, they will be executed (XSS). createElement + textContent are always safe — tags in the text stay text. Strings with innerHTML are acceptable only for your own markup that you know in advance.

A button inside a created element

Handlers can be attached to elements right after they are created — a closure will remember which item the button belongs to:

function addTask(text) {
  const li = document.createElement("li");
  li.append(text + " ");

  const done = document.createElement("button");
  done.textContent = "✓";
  done.addEventListener("click", () => li.classList.toggle("done"));

  li.append(done);
  document.querySelector("#todo").append(li);
}

Each li has its own button, and each button remembers its own li.

Summary

  • document.createElement("tag") — a new element; it isn't visible until inserted.
  • append / prepend / before / after — insert; remove() — remove; replaceChildren() — clear.
  • A list from an array: clear the container and create elements in a loop — a render() function.
  • User text — only through textContent, not through innerHTML.

New Item

Easy+10 XP

Write a function addItem(text): it creates a new <li> with this text and adds it to the end of the list #list. The function returns the created element.

addItem("Bread")  →  Milk, Bread
addItem("Eggs")   →  Milk, Bread, Eggs

Connect the connector to solve tasks

Task code runs on your own computer — faster and more reliable than in the browser. This needs the free CodeWithMe connector app. You only connect it once.

Looking for the connector on this computer…

  1. 1
    Download the connector for your system (Windows, macOS or Linux).Download the connectorOn the download page pick the file with your system in its name, e.g. windows-amd64.
  2. 2Run it and choose a folder for your solutions. It will install Python and Node.js there by itself when needed.
  3. 3
    Enter below the 6-digit code shown in the connector window (“Code for CodeWithMe”). If the browser asks about local network access — allow it.

The connector is open source (on GitHub), works only on your computer and runs code only after you enter the pairing code.