【发布时间】:2021-08-17 04:20:56
【问题描述】:
我正在创建一个待办事项列表应用程序并遇到以下问题:
加载或刷新网页后,所有待办事项的状态都会更改为“未选中”,尽管之前标记为已选中。 如果用户将待办事项标记为“已选中”,那么即使在页面加载后,其状态也应显示为“已选中”。
我应该如何解决页面加载时待办事项状态的本地存储问题?
刷新网页后,已勾选的待办事项如何仍显示为“已勾选”?
欢迎提出任何建议。
另见附件 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>
【问题讨论】:
-
刚刚通过修改“deleteCheckedTodo”功能并将pointerEvents设置为“none”找到了另一种处理本地存储问题的方法,这样即使在页面加载后也只会显示活动的待办事项。