Представим себе, что вы пишите таск-менеджер. Приложение должно работать как нативное: работать в офлайне также как в онлайне.
Основная концепция
Наш главный инструмент в построении такого приложения – localstorage.
С другими способами реализовать это я не знаком. Способ о котором я расскажу я придумал сам и мне он показался удачным.
Как это будет работать?
Итак, у нас есть список тасков:
<ul class="tasks"> <li class="task"> <p class="task__text" contenteditable="true">Eggs</p> <input type="checkbox"> </li> <li class="task"> <p class="task__text" contenteditable="true">Breads</p> <input type="checkbox"> </li> </ul> <button class="task__add-btn" type="button">New task</button>
Нам нужно хранить и обновлять текст задачи и статус выполнена/нет, а также реализовать добавление новой задачи.
Мы будем генерировать случайный ключ для каждой задачи и использовать его как идентификатор для каждой связанной хранимой информации в localstorage. По аналогии похоже на базы данных.
С чего начать?
Прежде всего мы будем смотреть есть ли уже какие-либо задачи в памяти. Все ключи будет храниться в одной строке
const savedTokens = localStorage.getItem('tokens'); const root = document.querySelector('.tasks'); let tokens = []; if (savedTokens != null) { tokens = savedTokens.split(', '); // ... }
Разберёмся пока с добавлением новой задачи, чтобы понимать концепцию хранения и использования хранимых данных.
При клике на добавить задачу в списке появится задача-шаблон, текст задачи можно редактировать. Неперь нужно описать всё это.
Создадим функцию, которая создаёт элемент с его содержимым по переданным в неё данным.
function getTemplate(token, data) { const task = document.createElement('li'); task.classList.add('task'); task.setAttribute('data-token', token); task.innerHTML = ` <p class="task__text" contenteditable="true">${data.text}</p> <input type="checkbox" ${data.input == 'true' ? 'checked' : ''}> `; return task; }
Опишем события для кнопки и для редактирования задачи:
const btnAddTask = document.querySelector('.task__add-btn'); btnAddTask.addEventListener('click', function(e) { e.preventDefault(); const newToken = randomToken(); tokens.push(newToken); const taskData = { text: 'Task`s title', input: false }; root.appendChild(getTemplate(newToken, taskData)); updateTokens(); updateEvent(newToken); });
Реализуем недостающие функции updateEvent и randomToken.
function updateEvent(token) { const task = root.querySelector(`[data-token="${token}"]`); const text = task.querySelector(`.task__text`); const input = task.querySelector(`input`); localStorage.setItem(`text-${token}`, text.innerHTML); localStorage.setItem(`input-${token}`, input.checked); text.addEventListener('input', function() { localStorage.setItem(`text-${token}`, text.innerHTML); }); input.addEventListener('click', function() { localStorage.setItem(`input-${token}`, input.checked); }); } function updateTokens() { localStorage.setItem('tokens', tokens.join(', ')); } function randomToken() { return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15); }
Отлично! Мы реализовали добавление задачи и сохранение их в localStorage. Осталось сделалть вывод задачь, которые уже сохранены.
Вывод сохранённых тасков
Для вывода тасков достаточно получить все ключи, распарсить их, вытянуть по каждому ключи текст таска и его статус. Далее просто создаём каждый таск в root: получаем таск с помощью getTemplate и вставляем его в root.
tokens.forEach(function(token) { const text = localStorage.getItem(`text-${token}`); const input = localStorage.getItem(`input-${token}`); root.appendChild(getTemplate(token, { text: text, input: input })); updateEvent(token); });
В общем, наш простейший таск-менеджер готов. Остаётся собрать всё в кучу.
