TaskBuild the todo list described above. The form adds a typed value as a new <li>. Each <li> has a child <span> with the text + a <button class='remove'>×</button>. Delegation on #list: clicking .remove deletes the li; clicking the span toggles 'done' on the li.
Build a Todo List in Vanilla JavaScript with Event Delegation
250 XP14 min
Theory
Putting C2 together
You'll combine every C2 idea into a working todo list:
- Form submit to add an item → C2-06 (preventDefault + FormData)
- createElement + textContent to render each item safely → C2-07
- Event delegation for the "remove" button on each item → C2-08
- classList for the "completed" line-through state → C2-04
- querySelector for everything else → C2-02
No framework. ~30 lines of JavaScript. Same skills run any non-trivial framework you'll meet later.
The shape
<form id="f"> <input id="text" required /> <button>Add</button> </form> <ul id="list"></ul>
const form = document.getElementById("f");
const input = document.getElementById("text");
const list = document.getElementById("list");
form.addEventListener("submit", (e) => {
e.preventDefault();
const value = input.value.trim();
if (!value) return;
const li = document.createElement("li");
const txt = document.createElement("span");
const btn = document.createElement("button");
txt.textContent = value;
btn.textContent = "×";
btn.className = "remove";
li.append(txt, btn);
list.appendChild(li);
input.value = "";
});
list.addEventListener("click", (e) => {
if (e.target.closest(".remove")) e.target.closest("li").remove();
else if (e.target.tagName === "SPAN") e.target.classList.toggle("done");
});Form adds → delegation handles remove + toggle. Two listeners total, regardless of list length.
🔒
Sign up to start coding
Theory is open to everyone. The interactive editor, live preview, and check are unlocked with a 7-day free trial — card required, cancel anytime.
Sign up — free trial →First 10 lessons in each track are free. No card needed for those.