我正在使用基本的javascript制作一個待辦事項應用程序。我在保存復選框輸入元素的檢查狀態并在頁面刷新時將其呈現出來時遇到了問題...我目前正在學習javascript,所以我對復選框的整個方法可能需要改變,所以告訴我最好的方法。
代碼如下:
let toDoListArray = JSON.parse(localStorage.getItem("items")) || {
toDoListArray: [
{
inputValue: "wash the dishes",
dateValue: "1-1-2023",
check: false,
},
{
inputValue: "checked example 2",
dateValue: "22-3-2025",
check: true,
},
],
};
addItem();
// the code i used for the checkboxes
let list = [];
document.querySelectorAll("input[type=checkbox]").forEach((element) => {
list.push(element);
let idx = list.indexOf(element);
if (toDoListArray[idx].check) {
element.setAttribute("checked", true);
} else if (!toDoListArray[idx].check) {
element.removeAttribute("checked");
}
element.addEventListener("change", () => {
if (element.checked) {
toDoListArray[idx].check = true;
} else {
toDoListArray[idx].check = false;
}
});
});
//end of checkboxes code
function addItem() {
let savedText = document.querySelector(".task-input");
let inputValue = savedText.value;
let savedDate = document.querySelector(".date-input");
let dateValue = savedDate.value;
let check = false;
if (inputValue) {
toDoListArray.push({
inputValue,
dateValue,
check,
});
}
addItemHTML();
savedText.value = "";
savedDate.value = "";
}
function deleteItem(index) {
toDoListArray.splice(index, 1);
addItemHTML();
}
function addItemHTML() {
let addedHTML = "";
for (let i = 0; i < toDoListArray.length; i++) {
let { inputValue, dateValue } = toDoListArray[i];
addedHTML += `
<div class="rendered-list-item">
<input id="check${i}" type="checkbox">
<label for="check${i}">${inputValue}</label>
<div>${dateValue}</div>
<button class="delete" onclick="deleteItem(${i})") >Delete</button>
</div>
`;
}
let jsonString = JSON.stringify(toDoListArray);
localStorage.setItem("items", jsonString);
document.querySelector(".list").innerHTML = addedHTML;
}
* {
margin: 0 auto;
padding: 0;
box-sizing: border-box;
font-family: sans-serif;
}
html {
scroll-behavior: smooth;
}
:root {
--form-hue: 226;
--form-saturation: 53%;
--form-light: 90%;
--form-bg-color: hsl(
var(--form-hue),
var(--form-saturation),
var(--form-light)
);
--header-bg-color: rgba(147, 147, 147, 0.6);
--header-color: aliceblue;
--list-bg-color: rgba(201, 199, 223, 0.3);
--main-bg-color: hsl(221, 70%, 95%);
--add-color: white;
}
body::-webkit-scrollbar {
width: 0.25rem;
}
body::-webkit-scrollbar-track {
background: #c9c9d7;
}
body::-webkit-scrollbar-thumb {
background: rgb(61, 61, 169);
}
main {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
background-color: var(--main-bg-color);
width: 60%;
height: 100%;
padding: 20px;
}
.header,
.form,
.list {
width: 100%;
padding: 10px;
margin: 10px;
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
}
.header {
border-radius: 10px;
background-color: var(--header-bg-color);
color: var(--header-color);
font-weight: bold;
}
.form {
background-color: var(--form-bg-color);
border-radius: 10px;
}
.list {
background-color: var(--list-bg-color);
border-radius: 5px;
flex-direction: column;
width: 100%;
}
.task-input,
.date-input,
.add {
border-radius: 10px;
padding: 7px;
margin: 5px;
border: none;
outline: none;
}
.add {
background-color: hsl(
var(--form-hue),
var(--form-saturation),
calc(var(--form-light) * 0.5)
);
color: var(--add-color);
transition: 0.2s;
}
.add:hover {
background-color: hsl(0, 0%, 71%);
scale: 1.07;
font-weight: bold;
cursor: pointer;
}
.add:active {
background-color: aliceblue;
}
.task-input:focus,
.date-input:focus {
background-color: hsl(240, 33%, 95%);
}
.task-input:hover,
.date-input:hover {
outline: 2px solid rgba(62, 93, 152, 0.6);
}
@media only screen and (max-width: 600px) {
main {
width: 100%;
}
}
.rendered-list-item {
display: flex;
justify-content: space-between;
align-items: center;
flex-direction: row;
background-color: hsl(0, 100%, 100%);
border-radius: 10px;
padding: 5px;
margin: 5px;
width: 95%;
flex-wrap: wrap;
}
.list .rendered-list-item:nth-child(even) {
background-color: hsla(222, 32%, 88%, 0.824);
}
.list .rendered-list-item:nth-child(even) div:nth-child(3) {
color: hsla(224, 43%, 72%, 0.824);
}
.rendered-list-item:hover {
background-color: hsla(0, 0%, 100%, 0.824);
}
.rendered-list-item label,
div,
button {
padding: 10px;
border-radius: 10px;
border: none;
}
.rendered-list-item button {
align-self: normal;
transition: 0.2s;
margin-right: 5px;
color: hsl(0, 0%, 71%);
}
.rendered-list-item button:hover {
scale: 1.08;
background-color: hsl(0, 65%, 55%);
color: white;
cursor: pointer;
}
.rendered-list-item div:nth-child(3) {
color: hsl(0, 0%, 71%);
}
.rendered-list-item label:nth-child(2) {
background-color: hsl(233, 100%, 98%);
margin-left: 5px;
flex: 1;
transition: 0.5s;
}
.rendered-list-item input[type="checkbox"]:checked + label {
font-weight: bold;
text-decoration: line-through;
color: hsl(0, 0%, 71%);
}
.rendered-list-item input[type="checkbox"] {
align-self: normal;
margin-left: 5px;
opacity: 0.6;
accent-color: hsl(262, 25%, 56%);
width: 0.9rem;
}
<!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" />
<title>vanilla javascipt ToDoList</title>
</head>
<body>
<main>
<p class="header">To-Do-List</p>
<div class="form">
<input placeholder="type the task" type="text" class="task-input" />
<input type="date" class="date-input" />
<button class="add" onclick="addItem()">Add</button>
</div>
<div class="list"></div>
</main>
</body>
</html>
您的代碼有兩個問題:
根據您的代碼,toDoListArray應該是這樣的:
[
{
inputValue: "wash the dishes",
dateValue: "1-1-2023",
check: false,
},
{
inputValue: "checked example 2",
dateValue: "22-3-2025",
check: true,
},
]
但是,在開始時,您試圖將toDoListArray設置為JSON . parse(local storage . getitem(& quot;項目& quot)),它遵循上面的數組格式。
并且因為您使用了邏輯OR運算符| | if JSON . parse(local storage . getitem(& quot;項目& quot))為假(null),那么我們將把toDoListArray設置為
{
toDoListArray: [
{
inputValue: "wash the dishes",
dateValue: "1-1-2023",
check: false,
},
{
inputValue: "checked example 2",
dateValue: "22-3-2025",
check: true,
},
],
}
如果你看到toDoListArray的兩個值是不同的,一個是對象,另一個是數組。 您可能沒有注意到這一點,因為您已經在localStorage中保存了正確的數組格式。
要解決這個問題,我們可以這樣做:
let toDoListArray = JSON.parse(localStorage.getItem("items")) || [
{
inputValue: "wash the dishes",
dateValue: "1-1-2023",
check: false,
},
{
inputValue: "checked example 2",
dateValue: "22-3-2025",
check: true,
},
];
第二個問題是您提到的,復選框的選中和未選中狀態在重新加載時并不持久。
這樣做的原因是,在復選框狀態改變時,您還需要在localStorage中更新它。像這樣:
element.addEventListener("change", () => {
if (element.checked) {
toDoListArray[idx].check = true;
} else {
toDoListArray[idx].check = false;
}
localStorage.setItem("items", JSON.stringify(toDoListArray));
});
最終代碼:
let toDoListArray = JSON.parse(localStorage.getItem("items")) || [{
inputValue: "wash the dishes",
dateValue: "1-1-2023",
check: false,
},
{
inputValue: "checked example 2",
dateValue: "22-3-2025",
check: true,
},
];
addItem();
// the code i used for the checkboxes
let list = [];
document.querySelectorAll("input[type=checkbox]").forEach((element) => {
list.push(element);
let idx = list.indexOf(element);
if (toDoListArray[idx].check) {
element.setAttribute("checked", true);
} else if (!toDoListArray[idx].check) {
element.removeAttribute("checked");
}
element.addEventListener("change", () => {
if (element.checked) {
toDoListArray[idx].check = true;
} else {
toDoListArray[idx].check = false;
}
localStorage.setItem("items", JSON.stringify(toDoListArray));
});
});
//end of checkboxes code
function addItem() {
let savedText = document.querySelector(".task-input");
let inputValue = savedText.value;
let savedDate = document.querySelector(".date-input");
let dateValue = savedDate.value;
let check = false;
if (inputValue) {
toDoListArray.push({
inputValue,
dateValue,
check,
});
}
addItemHTML();
savedText.value = "";
savedDate.value = "";
}
function deleteItem(index) {
toDoListArray.splice(index, 1);
addItemHTML();
}
function addItemHTML() {
let addedHTML = "";
for (let i = 0; i < toDoListArray.length; i++) {
let {
inputValue,
dateValue
} = toDoListArray[i];
addedHTML += `
<div class="rendered-list-item">
<input id="check${i}" type="checkbox">
<label for="check${i}">${inputValue}</label>
<div>${dateValue}</div>
<button class="delete" onclick="deleteItem(${i})") >Delete</button>
</div>
`;
}
localStorage.setItem("items", JSON.stringify(toDoListArray));
document.querySelector(".list").innerHTML = addedHTML;
}
* {
margin: 0 auto;
padding: 0;
box-sizing: border-box;
font-family: sans-serif;
}
html {
scroll-behavior: smooth;
}
:root {
--form-hue: 226;
--form-saturation: 53%;
--form-light: 90%;
--form-bg-color: hsl( var(--form-hue), var(--form-saturation), var(--form-light));
--header-bg-color: rgba(147, 147, 147, 0.6);
--header-color: aliceblue;
--list-bg-color: rgba(201, 199, 223, 0.3);
--main-bg-color: hsl(221, 70%, 95%);
--add-color: white;
}
body::-webkit-scrollbar {
width: 0.25rem;
}
body::-webkit-scrollbar-track {
background: #c9c9d7;
}
body::-webkit-scrollbar-thumb {
background: rgb(61, 61, 169);
}
main {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
background-color: var(--main-bg-color);
width: 60%;
height: 100%;
padding: 20px;
}
.header,
.form,
.list {
width: 100%;
padding: 10px;
margin: 10px;
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
}
.header {
border-radius: 10px;
background-color: var(--header-bg-color);
color: var(--header-color);
font-weight: bold;
}
.form {
background-color: var(--form-bg-color);
border-radius: 10px;
}
.list {
background-color: var(--list-bg-color);
border-radius: 5px;
flex-direction: column;
width: 100%;
}
.task-input,
.date-input,
.add {
border-radius: 10px;
padding: 7px;
margin: 5px;
border: none;
outline: none;
}
.add {
background-color: hsl( var(--form-hue), var(--form-saturation), calc(var(--form-light) * 0.5));
color: var(--add-color);
transition: 0.2s;
}
.add:hover {
background-color: hsl(0, 0%, 71%);
scale: 1.07;
font-weight: bold;
cursor: pointer;
}
.add:active {
background-color: aliceblue;
}
.task-input:focus,
.date-input:focus {
background-color: hsl(240, 33%, 95%);
}
.task-input:hover,
.date-input:hover {
outline: 2px solid rgba(62, 93, 152, 0.6);
}
@media only screen and (max-width: 600px) {
main {
width: 100%;
}
}
.rendered-list-item {
display: flex;
justify-content: space-between;
align-items: center;
flex-direction: row;
background-color: hsl(0, 100%, 100%);
border-radius: 10px;
padding: 5px;
margin: 5px;
width: 95%;
flex-wrap: wrap;
}
.list .rendered-list-item:nth-child(even) {
background-color: hsla(222, 32%, 88%, 0.824);
}
.list .rendered-list-item:nth-child(even) div:nth-child(3) {
color: hsla(224, 43%, 72%, 0.824);
}
.rendered-list-item:hover {
background-color: hsla(0, 0%, 100%, 0.824);
}
.rendered-list-item label,
div,
button {
padding: 10px;
border-radius: 10px;
border: none;
}
.rendered-list-item button {
align-self: normal;
transition: 0.2s;
margin-right: 5px;
color: hsl(0, 0%, 71%);
}
.rendered-list-item button:hover {
scale: 1.08;
background-color: hsl(0, 65%, 55%);
color: white;
cursor: pointer;
}
.rendered-list-item div:nth-child(3) {
color: hsl(0, 0%, 71%);
}
.rendered-list-item label:nth-child(2) {
background-color: hsl(233, 100%, 98%);
margin-left: 5px;
flex: 1;
transition: 0.5s;
}
.rendered-list-item input[type="checkbox"]:checked+label {
font-weight: bold;
text-decoration: line-through;
color: hsl(0, 0%, 71%);
}
.rendered-list-item input[type="checkbox"] {
align-self: normal;
margin-left: 5px;
opacity: 0.6;
accent-color: hsl(262, 25%, 56%);
width: 0.9rem;
}
<!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" />
<title>vanilla javascipt ToDoList</title>
</head>
<body>
<main>
<p class="header">To-Do-List</p>
<div class="form">
<input placeholder="type the task" type="text" class="task-input" />
<input type="date" class="date-input" />
<button class="add" onclick="addItem()">Add</button>
</div>
<div class="list"></div>
</main>
</body>
</html>
在我看來,當你點擊復選框時,你并沒有記錄對localStorage的更改。
element.addEventListener("change", () => {
if (element.checked) {
toDoListArray[idx].check = true;
} else {
toDoListArray[idx].check = false;
}
});
這個事件改變了選中狀態,但是沒有任何東西觸發您的localStorage.setItem,它只存在于addItemHTML中。