Pull to refresh

Сохранения данных пользователя после перезагрузки страницы

Reading time3 min
Views14K

Представим себе, что вы пишите таск-менеджер. Приложение должно работать как нативное: работать в офлайне также как в онлайне.


Основная концепция


Наш главный инструмент в построении такого приложения – 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);
});

В общем, наш простейший таск-менеджер готов. Остаётся собрать всё в кучу.


Рабочий таск менеджер доступен по ссылке.

Tags:
Hubs:
Total votes 28: ↑18 and ↓10+8
Comments14

Articles