JavaScript, DOM и localStorage

Практический пример: список задач. Создание элементов, обработка событий, делегирование и сохранение состояния между перезагрузками страницы.

DOM API События localStorage

Демонстрация: список задач

Добавьте несколько задач, отметьте выполненные и перезагрузите страницу — данные сохранятся в localStorage вашего браузера.

Задач нет

Разбор ключевых приёмов

1. Создание элемента

js
const li = document.createElement('li');
li.className = 'todo-item';
li.textContent = task.text;      // безопасно: текст, а не HTML
list.append(li);                 // добавление в конец списка

2. Делегирование событий

Вместо обработчика на каждой кнопке — один на весь список. Работает и для элементов, которые появятся позже.

js
list.addEventListener('click', (event) => {
  const btn = event.target.closest('[data-action="delete"]');
  if (!btn) return;                       // клик не по кнопке — игнорируем
  const id = btn.closest('.todo-item').dataset.id;
  removeTask(id);
});

3. Сохранение в localStorage

js
const KEY = 'mw-course-todos';

function save() {
  // localStorage хранит только строки — объект сериализуем в JSON
  localStorage.setItem(KEY, JSON.stringify(tasks));
}

function load() {
  try {
    return JSON.parse(localStorage.getItem(KEY)) || [];
  } catch (e) {
    return [];   // повреждённые данные не должны ломать приложение
  }
}
Безопасность. Никогда не вставляйте пользовательский ввод через innerHTML — это открывает путь к XSS-атакам. Используйте textContent или element.append(document.createTextNode(...)).

Три способа что-то сохранить на клиенте

ХранилищеОбъёмВремя жизниКогда использовать
localStorage~5 МБДо удаления вручнуюНастройки, черновики, прогресс
sessionStorage~5 МБДо закрытия вкладкиДанные одного сеанса, шаги мастера
document.cookie~4 КБЗадаётся вручнуюТолько то, что нужно серверу (сессии, согласия)
Все три варианта привязаны к домену и доступны из JavaScript, поэтому не храните там пароли и токены доступа.

Задание

  1. Добавьте к задаче дату создания и выводите её рядом с текстом.
  2. Сделайте кнопку «Редактировать»: по двойному клику текст заменяется на input.
  3. Добавьте сортировку: сначала активные, затем выполненные.
  4. Перенесите фильтр в адресную строку через location.hash, чтобы состояние фильтра тоже сохранялось.