Пошук уроків, статей та іншого контенту
Класичний навчальний проєкт: список завдань зі створенням, редагуванням, видаленням і збереженням стану.
Вимоги
Етапи
HTML-структура готова, статичний список завдань рендериться з масиву.
Почніть з мінімальної розмітки та функції рендеру, яка перебудовує список із єдиного джерела правди — масиву tasks.
index.html
<input id="new-task" type="text" placeholder="Нове завдання" />
<button id="add-btn">Додати</button>
<ul id="task-list"></ul>Можна додати нове завдання та видалити існуюче.
Додайте обробник для кнопки додавання та делеговане видалення — один слухач на контейнері списку замість обробника на кожному елементі.
app.js
document.getElementById("add-btn").addEventListener("click", () => {
const input = document.getElementById("new-task");
const text = input.value.trim();
if (!text) return;
tasks.push({ id: crypto.randomUUID(), text, completed: false });
input.value = "";
render();
});
document.getElementById("task-list").addEventListener("click", (event) => {
if (event.target.tagName !== "BUTTON") return;
const id = event.target.closest("li").dataset.id;
const index = tasks.findIndex((task) => task.id === id);
tasks.splice(index, 1);
render();
});Клік по завданню перемикає completed і візуально позначає завдання.
Працюють фільтри всі/активні/виконані, стан переживає перезавантаження сторінки.
Збережіть масив tasks у localStorage після кожної зміни та відновіть його при завантаженні сторінки.
app.js
function saveTasks() {
localStorage.setItem("tasks", JSON.stringify(tasks));
}
function loadTasks() {
const saved = localStorage.getItem("tasks");
return saved ? JSON.parse(saved) : [];
}
let tasks = loadTasks();Todo-застосунок — гарний перший проєкт, щоб застосувати роботу зі станом, подіями та рендерингом списків на практиці. Почніть з найпростішої версії на чистому JavaScript, а потім спробуйте переписати її на TypeScript.
Розмітіть HTML-структуру: поле вводу, кнопка додавання, список завдань, фільтри.
Реалізуйте додавання завдання в масив стану та рендеринг списку.
Додайте позначення виконаним (клік по завданню перемикає стан) і видалення.
Додайте фільтрацію списку за статусом.
Збережіть стан у localStorage і відновлюйте його при завантаженні сторінки.
Тримайте єдине джерело правди — масив завдань у стані — і завжди перерендерюйте список із нього, а не редагуйте DOM напряму.
Підказки
Зберігайте завдання як масив об'єктів { id, text, completed }, а не як окремі DOM-елементи.
Використайте delegation — один обробник кліків на контейнері списку — замість навішування обробника на кожен елемент.
Пов'язані уроки
app.js
const tasks = [];
function render() {
const list = document.getElementById("task-list");
list.innerHTML = "";
for (const task of tasks) {
const li = document.createElement("li");
li.textContent = task.text;
li.dataset.id = task.id;
list.appendChild(li);
}
}
render();Викликайте render() після будь-якої зміни масиву tasks — ніколи не редагуйте DOM напряму в обробниках подій.
Не забудьте додати кнопку видалення для кожного завдання всередині render():
app.js — render(), фрагмент
li.innerHTML = `${task.text} <button>Видалити</button>`;Викликайте saveTasks() одразу після кожної зміни масиву — додавання, видалення, перемикання completed — так стан завжди синхронізований зі сховищем.
Фільтр (всі/активні/виконані) — це лише те, що показує render(); сам масив tasks не змінюється при перемиканні фільтра.