Как сделать сохранение задач(ToDo) в localStorage

Как сделать сохранение задач в localStorage, что бы после перезагрузки страницы они не пропадали?

const contant__form = document.querySelector('.contant__form');
const container__task = document.querySelector('.container__task');


contant__form.addEventListener('submit',  addTask);
container__task.addEventListener('click', delTask);


function addTask(e) {
    e.preventDefault()
    const input = document.querySelector('.contant__form-input');

    if (!input.value == "") {
        
        const Html =`<div class="task">
                        <h1>${input.value}</h1>

                        <div class="btn__task">
                            <div class="container__del-task" data-action="del">
                                 <span class="container__del-btn"></span>
                            </div>
                        </div>
                    </div>`;

        container__task.innerHTML += Html
        
        input.value = "";
        input.focus();
    };
};



function delTask(e) {
    self = e.target;

    if (self.classList.contains('container__del-task')) {
        const parentTask = e.target.closest('.task');
        parentTask.remove();
    };

    
};
.ToDo{
    background-color: #485268;
    padding-top: 50px;
    padding-bottom: 20px;
    height: 100%;
}

.container{
    max-width: 1000px;
    margin: 0 auto;
    padding: 10px 15px;
}

.grid{
    display: grid;
    grid-template-columns: minmax(300px, 600px) 1fr;

    gap: 20px;

    align-items: center;
}

@media (max-width: 880px) {
    .grid{
        display: grid;
        grid-template-columns: minmax(100px, 900px);
    
        gap: 20px;
    
        align-items: center;
    }
    
}

.container__task{
    background-color: #626f8b;

    border-radius: 5px;
    padding: 10px 15px;
}

.task{
    display: flex;
    justify-content: space-between;
    align-items: center;

    background-color: #7c8db3;

    padding: 10px 15px;
    margin: 10px 0px;

    border: 1px solid black;
    border-radius: 10px;

    overflow: hidden;
}

.task h1{
    font-size: 1.2rem;

}


.btn__task{
    display: flex;
    justify-content: center;
}



.container__del-task{
    width: 50px;
    height: 50px;
    
    background-color: #90a4d1;
    border: 1px solid black;

    border-radius: 5px;
}

.container__del-task:hover{

    background-color: #6f91e0;
}

.container__del-task{
    position: relative;
}

.container__del-btn::after{
    content: "";
    position: absolute;

    top: 25px;
    left: 5px;

    transform: rotate(50deg);
    
    width: 40px;
    height: 2px;

    background-color: black;
}

.container__del-btn::before{
    content: "";
    position: absolute;

    top: 25px;
    left: 5px;

    transform: rotate(-50deg);
    
    width: 40px;
    height: 2px;

    background-color: black;
}

.contant__form{
    display: flex;
    flex-direction: column;

    justify-content: center;

    max-width: 500px;
    background-color: #626f8b;

    border-radius: 5px;

    padding: 10px 5px;

    
}

.contant__form-input{
    padding: 10px;
    margin: 10px;

    width: 300px;
    border-radius: 10px;

    background-color: #90a4d1;

    font-size: 1.1rem;

}

.contant__form-btn{
    display: flex;


    padding: 10px;
    margin: 10px;

    width: 320px;
    border-radius: 10px;

    background-color: #90a4d1;

    font-size: 1.1rem;
    
}
<section class="ToDo">
        <div class="container">
            <div class="grid">
                <div class="container__task">

                </div>

                <form class="contant__form">
                    <input type="text" class="contant__form-input" placeholder="Введите задачу">
                    <button class="contant__form-btn">Отправить</button>
                </form>
            </div>
        </div>
    </section>`


Ответы (1 шт):

Автор решения: SwaD

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

Основные моменты реализации:

  • Каждой задаче нужно присвоить свой уникальный ID для поиска(в примере выбран unix-timestamp - new Date().getTime())
  • Каждое изменение состояния списка задач, необходимо сохранять в localStorage

Ниже пример того, как это можно сделать. Код с комментариями и описанием JSDoc

/**
 * @typedef {Object} ToDoItemType
 * @property {number} id ID задания
 * @property {string} text Текст задания
 */

/** @type ToDoItemType[] */
let taskList = [];
/** Сохраняет текущий ToDo в localStorage */
const saveLocal = () => localStorage.setItem('tasklist', JSON.stringify(taskList));

document.addEventListener('DOMContentLoaded', () => {
  /* Пытаемся получить список заданий из хранилища */
  try {
    taskList = JSON.parse(localStorage.getItem('tasklist') ? ? '[]');
  } catch (e) {
    // Обработчики, если что то пошло не так
    console.error(e);
  }
  /* Для каждого элемента отрисовываем задание на странице */
  taskList.forEach(item => addTaskInDom(item.text, item.id, false));
})
/** @type {HTMLInputElement} */
const taskInput = document.getElementById('taskText');
/** @type {HTMLButtonElement} */
const addButton = document.getElementById('addButton');
/** @type {HTMLDivElement} */
const taskContainer = document.getElementById('taskBox');

addButton.addEventListener('click', () => {
  /* Создаем новое задание */
  addTaskInDom(taskInput.value, new Date().getTime());
  taskInput.value = ''; // Зачищаем инпут
});

/**
 * Добавляет новое задание на страницу
 * @param {string} task ID задания
 * @param {number} idTask Текст задания
 * @param {boolean} isNew Признак нового задания
 */
function addTaskInDom(task, idTask, isNew = true) {
  /** @type {ToDoItemType} */
  const taskBody = {
    id: idTask,
    text: task,
  }
  /* Создаем обертку для задания */
  const div = document.createElement('div');
  div.className = 'taskItem'; // Добавляем класс
  /* Создаем текст задания*/
  const taskText = document.createElement('div');
  taskText.className = 'taskItemText'; // Добавляем класс
  taskText.innerText = task; // Добавляем текст
  /* Создаем кнопку удаления задания*/
  const buttonDelete = document.createElement('button');
  buttonDelete.innerText = 'Удалить'; // Текст кнопки
  /* Вешаем обработчик на нажатие кнопки */
  buttonDelete.addEventListener('click', () => {
    div.remove(); // Удалить со страницы
    taskList = taskList.filter(it => it.id !== idTask); // Изменить текущее состояние
    saveLocal(); // Сохранить
  });
  div.appendChild(taskText); // Добавляем в контейнер текст
  div.appendChild(buttonDelete); // Ддобавляем кнопку
  taskContainer.appendChild(div); // Добавляем задание в контейнер
  /* Если это создание задания, пушим и сохраняем в хранилище */
  if (isNew) {
    taskList.push(taskBody); // Пушим задние
    saveLocal(); // Сохраняем
  }
}
.container {
  display: flex;
  flex-direction: column;
  padding: 20px;
}

.taskItem {
  display: flex;
}

.taskItemText {
  width: 200px;
  border-bottom: #bfbfbf 1px solid;
}
<div id="inpdiv">
  <label for="taskText">Введите текст задачи: </label>
  <input type="text" id="taskText" />
  <button id="addButton">Добавить</button>
</div>
<div class="container" id="taskBox">

</div>

P.S. В сниппет оформлено для красоты, работать не будет из-за самого localStorage(запрещено в сниппетах).

→ Ссылка