Проблема с локальным хранилищем со статусом задач-элементов при загрузке страницы

#javascript #local-storage

Вопрос:

Я создаю приложение со списком задач и застрял на следующей проблеме:

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

Как я должен решить эту проблему с локальным хранилищем со статусом задач при загрузке страницы?

Как проверенный элемент задачи может по-прежнему отображаться как «проверенный» после обновления веб-страницы?

Любые предложения приветствуются.

Также смотрите прилагаемый jsFiddle: jsFiddle

 "use strict";

const todoForm = document.querySelector(".todo-form");
const todoInput = document.querySelector(".todo-input");
const todoBtn = document.querySelector(".todo-btn");
const todoList = document.querySelector(".todo-list");

function addTodo(e) {
  e.preventDefault();

  const newTodoDiv = document.createElement("div");
  newTodoDiv.classList.add("todo");

  const todoTitle = document.createElement("li");
  todoTitle.innerText = todoInput.value.trim();
  if (todoTitle.innerText === "") return;
  todoTitle.classList.add("todo-item");
  newTodoDiv.appendChild(todoTitle);

  saveTodos(todoInput.value);
  todoInput.value = "";

  const checkedBtn = document.createElement("button");
  checkedBtn.innerHTML = "<i class='far fa-check-square'></i>";
  checkedBtn.classList.add("checked-btn");
  newTodoDiv.appendChild(checkedBtn);

  const delBtn = document.createElement("button");
  delBtn.innerHTML = "<i class='far fa-trash-alt'></i>";
  delBtn.classList.add("del-btn");
  newTodoDiv.appendChild(delBtn);

  todoList.appendChild(newTodoDiv);
}

function deleteCheckedTodo(e) {
  const element = e.target;
  if (element.classList[0] === "del-btn") {
    const todo = element.parentElement;
    todo.classList.add("fadeAway");
    clearTodos(todo);
    todo.addEventListener("transitionend", () => {
      todo.remove();
    });
  } else if (element.classList[0] === "checked-btn") {
    const todo = element.parentElement;
    todo.classList.toggle("done");
  }
}

function handleLocalStorage() {
  let localTodos;
  if (localStorage.getItem("localTodos") === null) {
    localTodos = [];
  } else {
    localTodos = JSON.parse(localStorage.getItem("localTodos"));
  }
  return localTodos;
}

function saveTodos(todo) {
  let localTodos = handleLocalStorage();
  localTodos.push(todo);
  localStorage.setItem("localTodos", JSON.stringify(localTodos));
}

function getTodos(todo) {
  let localTodos = handleLocalStorage();
  localTodos.forEach(function(todo) {
    const newTodoDiv = document.createElement("div");
    newTodoDiv.classList.add("todo");

    const todoTitle = document.createElement("li");
    todoTitle.innerText = todo;
    todoTitle.classList.add("todo-item");
    newTodoDiv.appendChild(todoTitle);

    const checkedBtn = document.createElement("button");
    checkedBtn.innerHTML = "<i class='far fa-check-square'></i>";
    checkedBtn.classList.add("checked-btn");
    newTodoDiv.appendChild(checkedBtn);

    const delBtn = document.createElement("button");
    delBtn.innerHTML = "<i class='far fa-trash-alt'></i>";
    delBtn.classList.add("del-btn");
    newTodoDiv.appendChild(delBtn);

    todoList.appendChild(newTodoDiv);
  });
}

function clearTodos(todo) {
  let localTodos = handleLocalStorage();
  const todoIndex = todo.children[0].innerText;
  localTodos.splice(localTodos.indexOf(todoIndex), 1);
  localStorage.setItem("localTodos", JSON.stringify(localTodos));
}

todoForm.addEventListener("submit", addTodo);
todoList.addEventListener("click", deleteCheckedTodo);
document.addEventListener("DOMContentLoaded", getTodos); 
 *,
*::before,
*::after {
  margin: 0;
  padding: 0;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
}

body {
  display: flex;
  font-family: Monospace, sans-serif;
  font-size: 16px;
  background: grey;
}

form {
  padding-bottom: 35px;
}

form > input {
  width: 338px;
  font-family: inherit;
}

form > input, form > button {
  padding: 10px;
  font-size: 1rem;
  border: none;
  background: #FFF;
  border-radius: 5px;
  box-shadow: rgba(50, 50, 93, .25) 0 13px 27px -5px, rgba(0, 0, 0, .3) 0 8px 16px -8px;
  outline: none;
}

form > input:focus, form > button:focus { 
  box-shadow: rgba(3, 102, 214, .3) 0 0 0 3px;
}

form > input:hover, form > button:hover { 
  box-shadow: rgba(3, 102, 214, .3) 0 0 0 3px;
  cursor: pointer;
}

.todo {
  margin: -10px;
  transition: all .5s ease;
}

.todo-container {
  min-width: 363px;
  max-width: 363px;
  margin: 0 auto;
  word-wrap: break-word;
  word-break: break-all;
}

.todo-list {
  list-style: none;
}

.todo-item {
  background: #FFF;
  font-size: 1.5rem;
  border-radius: 5px;
  box-shadow: rgb(204, 219, 232) 3px 3px 6px 0 inset, rgba(255, 255, 255, .5) -3px -3px 6px 1px inset;
}

.todo-item:hover {
  box-shadow: rgba(3, 102, 214, .3) 0 0 0 3px;
  cursor: pointer;
}

.checked-btn {
  background: #74C365;
  transform: translate(390px, -30.5px);
  margin-right: 8px;
}

.del-btn {
  background: #FF0000;
  transform: translate(390px, -30.5px);
}

.checked-btn, .del-btn {
  border: none;
  border-radius: 5px;
  cursor: pointer;
  font-size: 1rem;
  padding: 8.5px;
}

.checked-btn:hover, .del-btn:hover {
  box-shadow: rgba(0, 0, 0, .4) 0 2px 4px, rgba(0, 0, 0, .3) 0 7px 13px -3px, rgba(0, 0, 0, .2) 0 -3px 0 inset;
}

.fa-check-square, .fa-trash-alt {
  pointer-events: none;
}

.done {
  text-decoration: line-through;
  opacity: .5;
}

.fadeAway {
  opacity: 0;
} 
 <!DOCTYPE html>
<html lang="en">

  <head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
    <title>Todo List App</title>

    <link rel="stylesheet" type="text/css" href="src/css/toDoList.css">
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css" integrity="sha384-DyZ88mC6Up2uqS4h/KRgHuoeGwBcD4Ng9SiP4dIRy0EXTlnuz47vAwmeGwVChigm" crossorigin="anonymous">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/>
  </head>

  <body>

    <main>
        <form class="todo-form">
          <input class="todo-input" type="text" placeholder="E.g. build a website">
          <button class="todo-btn" type="submit">
            <i class="far fa-plus-square"></i>
          </button>
        </form>
        <div class="todo-container">
          <ul class="todo-list"></ul>
        </div>
    </main>

    <script src="toDoList.js" defer></script>

  </body>

</html> 

Комментарии:

1. Просто нашел другой способ решить проблему с локальным хранилищем, изменив функцию «deleteCheckedTodo»и установив для событий указателя значение «нет», чтобы отображались только активные элементы задач, даже после загрузки страницы.

Ответ №1:

Изменить

 todoForm.addEventListener("submit", addTodo);
 

Для

 todoBtn.addEventListener("click", addTodo);