์ฑ๋ฆฐ์ง์์ ์ฌํ๊ณผ์ (๋ก์ปฌ ์คํ ๋ฆฌ์ง, ์ฒดํฌ๋ฐ์ค)๋ฅผ ์ถ๊ฐํ ๊ธ์ด๋ค.
ํ์ ์กฐ๊ฑด
- index.html์ ์๋ input ์์์ ์ ๋ ฅ๋ ๊ฐ(value)๊ณผ button ์์๋ฅผ ๋ณ์์ ํ ๋นํฉ๋๋ค.
- ์๋ก์ด li ์์๋ฅผ ๋ง๋ค๊ณ input ์์์ ์ ๋ ฅ๋ ๊ฐ์ textContent๋ก ๊ฐ๋๋ก ํฉ๋๋ค.
- li ์์๋ ํด๋ฆญํ๋ฉด ํด๋น li ์์๊ฐ ์ง์์ง๋ delete ๋ฒํผ์ ๊ฐ์ง๊ณ ์์ด์ผ ํฉ๋๋ค.
- ์ ๋ ฅ์ฐฝ์ ์ด๊ธฐํ๋์ด์ผ ํฉ๋๋ค.
- ๋ง์ฝ ์ ๋ ฅ์ฐฝ์ ์๋ฌด๊ฒ๋ ์ ๋ ฅํ์ง ์์ ๊ฒฝ์ฐ alert๋ก ์ ์ ์๊ฒ ์ ๋ ฅ์ ์์ฒญํด์ผ ํฉ๋๋ค.
- 3.์ ์ญ์ ๋ฒํผ ๋ง๋ค๊ธฐ ๐ฝ
const deleteBtn = document.createElement('button');
deleteBtn.onclick = function () {
this.parentElement.remove();
};
์ฌํ ๋์ ๊ณผ์
- ์ ๋ ฅํ TO-DO๊ฐ Local Storage์ ์ ์ฅ๋์ด ์๋ก ๊ณ ์นจ ํ์๋ ์ ์ง๋๋๋ก ํด๋ณด์ธ์.
- ํ ์ผ ํญ๋ชฉ์ ์๋ฃ ํ์๋ฅผ ํ ์ ์๋ ์ฒดํฌ๋ฐ์ค๋ฅผ ์ถ๊ฐํด ๋ณด์ธ์.
- TO-DO ๋ฆฌ์คํธ๋ฅผ ๋๋๊ทธ์ค๋๋กญ์ผ๋ก ์ ๋ ฌํ ์ ์๋ ๋ฐฉ๋ฒ์ ๊ฒ์ํ๊ณ ์ ์ฉํด ๋ณด์ธ์.
https://stackblitz.com/edit/vitejs-vite-cqztxjtt?embed=1&file=script.js&theme=dark
JavaScript 5์ผ์ฐจ (67%) (forked) - StackBlitz
๊ธฐ๋ณธ ์กฐ๊ฑด + ์ฒดํฌ๋ฐ์ค ๊ธฐ๋ฅ
stackblitz.com
์ผ๋จ ๊ธฐ์กด ํ์ ๊ฑฐ์ ๊ฑด๋๋ฆฌ์ง ์๊ณ ๊ธฐ๋ณธ ์กฐ๊ฑด + ์ฌํ 2๋ฒ (์ฒดํฌ๋ฐ์ค)๊น์ง๋ ํด๊ฒฐํ ์ ์์๋ค.
์ฝ๋ ๐ฝ
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>ํ ์ผ ๋ชฉ๋ก</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="todo-container">
<div id="inputbox">
<input type="text" id="todo-input" placeholder="ํ ์ผ์ ์
๋ ฅํ์ธ์" />
<button id="add-btn">์ถ๊ฐ</button>
</div>
<ul id="todo-list"></ul>
</div>
<script src="script.js"></script>
</body>
</html>
style.css
body {
font-family: Arial, sans-serif;
}
ul {
list-style: none;
padding: 0;
}
.todo-container {
max-width: 400px;
margin: auto;
padding: 20px;
border: 1px solid #ddd;
border-radius: 5px;
}
#inputbox {
display: flex;
justify-content: space-between;
}
#todo-input {
width: 70%;
padding: 10px;
margin-right: 5px;
border: 1px solid #ccc;
border-radius: 4px;
}
#add-btn {
width: 30%;
padding: 10px 20px;
background-color: #007bff;
color: white;
white-space: nowrap;
border: none;
border-radius: 4px;
cursor: pointer;
}
#add-btn:hover {
background-color: #0056b3;
}
#todo-list {
margin-top: 20px;
}
#todo-list li {
cursor: pointer;
padding: 10px;
border-bottom: 1px solid #ddd;
display: flex;
align-items: center;
}
#todo-list li > span {
width: 100%;
margin-left: 5px;
}
#todo-list li:last-child {
border-bottom: none;
}
.delete-btn {
margin-left: auto;
background-color: red;
color: white;
border: none;
padding: 5px 10px;
border-radius: 5px;
cursor: pointer;
white-space: nowrap;
}
script.js
// 1. index.html์ ์๋ input ์์์ ์
๋ ฅ๋ ๊ฐ(value)๊ณผ button ์์๋ฅผ ๋ณ์์ ํ ๋นํฉ๋๋ค.
const todoInput = document.getElementById('todo-input');
const todoList = document.getElementById('todo-list');
const addBtn = document.getElementById('add-btn');
// 0. ๋ฒํผ์ ํด๋ฆญํ์ ๋ ์คํ๋๋ ์ด๋ฒคํธ ํจ์์
๋๋ค.
addBtn.addEventListener('click', function () {
// trim() : ๊ณต๋ฐฑ์ ์ง์์ฃผ๋ ํจ์๋ก value์ ๊ฐ์ผ๋ก " "์ด ๋ค์ด์์ ๋ ๋ฑ์ ๊ณต๋ฐฑ์ผ๋ก๋ง ๊ตฌ์ฑ๋ ํ ์ผ ์ถ๊ฐ๋ฅผ ๋ฐฉ์งํ๋ค.
if (todoInput.value.trim() !== '') {
// 2. ์๋ก์ด li์์๋ฅผ ๋ง๋ค๊ณ
const li = document.createElement('li');
// ์ฌํ2) ํ ์ผ ํญ๋ชฉ์ ์๋ฃ ํ์๋ฅผ ํ ์ ์๋ ์ฒดํฌ๋ฐ์ค๋ฅผ ์ถ๊ฐํด ๋ณด์ธ์.
// ์ฒดํฌ๋ฐ์ค ์ถ๊ฐ
const checkBtn = document.createElement('input');
checkBtn.type = 'checkbox';
li.append(checkBtn);
// change ์ด๋ฒคํธ : ์ฒดํฌ๋ฐ์ค์ผ ๋๋ ์ฒดํฌํ๊ฑฐ๋ ํด์ ํ ๋ ๊ฐ์ด ๋ณ๊ฒฝ๋๋ค.
checkBtn.addEventListener('change', function () {
// checked : ํด๋น ์ฒดํฌ๋ฒํผ์ ์์ฑ์ผ๋ก checked๊ฐ ๋ถ์์ ๋
if (checkBtn.checked) {
// nextElementSibling : ๋ถ๋ชจ์ ์์ ๋ชฉ๋ก์์ ์ง์ ๋ ์์(์ฒดํฌ๋ฒํผ) ๋ฐ๋ก ๋ค์ ์๋ ์์๋ฅผ ๋ฐํ
this.nextElementSibling.style.textDecoration = 'line-through';
} else {
this.nextElementSibling.style.textDecoration = '';
}
});
// 2. input ์์์ ์
๋ ฅ๋ ๊ฐ์ textContent๋ก ๊ฐ๋๋ก ํฉ๋๋ค.
// ํ ์ผ ๋ด์ฉ ์ถ๊ฐ
const todoContent = document.createElement('span');
todoContent.textContent = todoInput.value;
li.append(todoContent);
// 3. li ์์๋ ํด๋ฆญํ๋ฉด ํด๋น li ์์๊ฐ ์ง์์ง๋ delete ๋ฒํผ์ ๊ฐ์ง๊ณ ์์ด์ผ ํฉ๋๋ค.
// deleteBtn ์ถ๊ฐ
const deleteBtn = document.createElement('button');
// ๋ฒํผ์ ๊ฐ๋จํ๊ฒ css ์ ์ฉ์ ํ๊ธฐ์ํด ํด๋์ค ๋ถ์ฌ
deleteBtn.className = 'delete-btn';
deleteBtn.textContent = '์ญ์ ';
li.append(deleteBtn);
deleteBtn.onclick = function () {
// this.parentElement : ์ด ๊ฐ์ฒด์ ๋ถ๋ชจ ์์ (์ฆ deleteBtn์ด ํด๋ฆญ๋ ๋ถ๋ชจ liํ๊ทธ)
this.parentElement.remove();
};
// li๋ฅผ ul(#todo-list)์์ถ๊ฐ
todoList.append(li);
// 4. ์
๋ ฅ์ฐฝ์ ์ด๊ธฐํ๋์ด์ผ ํฉ๋๋ค.
todoInput.value = '';
} else {
// 5. ๋ง์ฝ ์
๋ ฅ์ฐฝ์ ์๋ฌด๊ฒ๋ ์
๋ ฅํ์ง ์์ ๊ฒฝ์ฐ alert๋ก ์ ์ ์๊ฒ ์
๋ ฅ์ ์์ฒญํด์ผ ํฉ๋๋ค.
alert('๋ด์ฉ์ ์
๋ ฅํด์ฃผ์ธ์!');
return;
}
});
* ์ฒดํฌ๋ฐ์ค๋ฅผ ์ฒดํฌํ ๋์ ์ด๋ฒคํธ๋ change์ด๋ค.
change ์ด๋ฒคํธ์ ๋ํด ์์ธํ ๋ด์ฉ์ : https://developer.mozilla.org/ko/docs/Web/API/HTMLElement/change_event
์ด์ ์ฌํ 1๋ฒ, ๋ก์ปฌ ์คํ ๋ฆฌ์ง๋ฅผ ๊ตฌํํ๊ณ ์ ํ๋ ค๋ ์ฝ๋๋ฅผ ์ข ๋ฏ์ด๋ด์ผ ํ ํ์๊ฐ ์๊ฒผ๋ค.
๊ธฐ์กด ์ฝ๋์์๋ add-btn์ ํด๋ฆญํ ๋ค์ ํญ๋ชฉ์ด ์ถ๊ฐ๊ฐ ๋๊ณ , ์ถ๊ฐ๋ ํญ๋ชฉ์ ์ญ์ / ์ฒดํฌ๊ฐ ๊ฐ๋ฅํ๋ค๋ง ์ง๊ธ๊น์ง๋ ๋ฌธ์ ๊ฐ ์์๋ค. ์๋ํ๋ฉด ์ด ํ์ด์ง๋ ์ด์ฐจํผ ์๋ก๊ณ ์นจ ํ๋ฉด ๋ด์ฉ์ด ์ ๋ถ ์ฌ๋ผ์ง๊ธฐ ๋๋ฌธ์, ๊ธฐ๋ฅ๋ค์ ํ ์คํธํด ๋ณด๋ ค๋ฉด ๊ผญ ํ ๋ฒ์ ํ ์ผ์ ์ถ๊ฐํ๊ธฐ ์ํด add-btn์ ํด๋ฆญํด์ผ ํ๊ธฐ ๋๋ฌธ์ด๋ค.
ํ์ง๋ง ์ด์ ์ถ๊ฐํ ๋ชฉ๋ก๋ค์ ๋ก์ปฌ ์คํ ๋ฆฌ์ง์ ์ ์ฅํ๊ธฐ, ์๋ก๊ณ ์นจ์ ํด๋ ๋ก์ปฌ ์คํ ๋ฆฌ์ง์ ์๋ ๋ด์ฉ์ ๋ถ๋ฌ์ค๊ธฐ๋ฅผ ํด์ผ ํ๊ธฐ ๋๋ฌธ์ ํจ์๋ด ๋ด์ฉ๋ค์ ์ข ๋๋ ์ผ ํ๋ค.
script.js ๐ฝ
const toDocontainer = document.getElementById("todo-container");
const todoInput = document.getElementById("todo-input");
const todoList = document.getElementById("todo-list");
const addBtn = document.getElementById("add-btn");
// ใ๏ฝฅ๏พ*๏ฝก๏ฝฅ ๏ฝก*๏ฝฅ๏พ ๋ถ๋ฌ์ค๊ธฐ ๏ฝฅ๏พ*๏ฝก๏ฝฅ ๏ฝก*๏ฝฅ๏พ
const todoStorage = JSON.parse(localStorage.getItem("todoStorage"));
if (todoStorage !== null) {
for (let i = 0; i < todoStorage.length; i++) {
// todoStorage์ [i]๋ฒ์งธ ๊ฐ์ makeToDoList์ ๋ฃ์ด๋
makeToDoList(todoStorage[i]);
}
}
// add-btn ๋ฒํผ ํด๋ฆญ ์ ์ด๋ฒคํธ
addBtn.addEventListener("click", function () {
if (todoInput.value.trim() !== "") {
makeToDoList();
} else {
alert('๋ด์ฉ์ ์
๋ ฅํด์ฃผ์ธ์.')
}
});
// ๋ฆฌ์คํธ ์ถ๋ ฅ ํจ์
function makeToDoList(storageList) {
const li = document.createElement("li");
const checkBtn = document.createElement("input");
const todoContent = document.createElement("span");
const deleteBtn = document.createElement("button");
// local storage์ ์ ์ฅ๋์ด ์๋ค๋ฉด
if (storageList) {
todoInput.value = storageList.contents;
if (storageList.check === true) {
li.classList.add("checked");
checkBtn.checked = true;
}
}
// ์ฒดํฌ๋ฐ์ค ์ถ๊ฐ
checkBtn.type = "checkbox";
li.append(checkBtn);
checkBtn.addEventListener("change", function () {
// toggle("ํด๋์ค๋ช
") : ํด๋น ํด๋์ค๊ฐ ์กด์ฌํ๋ค๋ฉด ์ ๊ฑฐ ํ false๋ฅผ ๋ฐํ, ์กด์ฌํ์ง ์์ผ๋ฉด ์ถ๊ฐ ํ true ๋ฐํ
this.parentElement.classList.toggle("checked");
});
// ํ ์ผ ๋ด์ฉ ์ถ๊ฐ
todoContent.textContent = todoInput.value;
li.append(todoContent);
// deleteBtn ์ถ๊ฐ
deleteBtn.className = "delete-btn";
deleteBtn.textContent = "์ญ์ ";
li.append(deleteBtn);
deleteBtn.onclick = function () {
this.parentElement.remove();
};
// li ์ถ๊ฐ
todoList.append(li);
// input์ฐฝ ์ด๊ธฐํ
todoInput.value = "";
}
// ใ๏ฝฅ๏พ*๏ฝก๏ฝฅ ๏ฝก*๏ฝฅ๏พ ์ ์ฅํ๊ธฐ ๏ฝฅ๏พ*๏ฝก๏ฝฅ ๏ฝก*๏ฝฅ๏พ
document.getElementById("saveStorage").addEventListener("click", function () {
// localStorage์ ๋ด์ array
const todoStorage = [];
for (let i = 0; i < todoList.children.length; i++) {
const todoObject = {
contents: todoList.children[i].querySelector("span").textContent,
// classList.contains("ํด๋์ค๋ช
") : ํด๋น ํด๋์ค ๋ช
์ด ํด๋น ์์์ ํฌํจ๋์ด์๋์ง
check: todoList.children[i].classList.contains("checked"),
};
todoStorage.push(todoObject);
}
console.log(todoStorage);
// JSON.stringfy() : ๋ณ์๋ฅผ ๋ฌธ์์ด๋ก ๋ฐ๊ฟ array ๊ทธ ์์ฒด๋ฅผ ๋ฌธ์์ด๋ก ๋ง๋ ๋ค.
localStorage.setItem("todoStorage", JSON.stringify(todoStorage));
});
๋ก์ปฌ ์คํ ๋ฆฌ์ง ์ ์ฅ / ๋ถ๋ฌ์ค๊ธฐ ์ธ์๋ ํฌ๊ฒ ๋ฌ๋ผ์ง ์ ์ ์์ผ๋, ๋ถ๋ฌ์ค๊ธฐ ์์๋ ๋ฆฌ์คํธ ์ถ๋ ฅ์ ํด์ค์ผ ํ๊ธฐ ๋๋ฌธ์ ํจ์๋ก ๋ฐ๋ก ๋ถ๋ฆฌํด ์ฃผ๋ฉด์ ๋ฐ๋๊ฒ ๋ ์ ์ด ์๋ค.
1. addBtn์ ๋๋ ์ ๋ (ํ ์ผ์ ์ถ๊ฐํ ๋)์ ํจ์ ๋ถ๋ฆฌ
์์ ์
const addBtn = document.getElementById('add-btn');
addBtn.addEventListener('click', function () {
if (todoInput.value.trim() !== '') {
const li = document.createElement('li');
// ....... ์๋ต ........
todoList.append(li);
todoInput.value = '';
} else {
alert('๋ด์ฉ์ ์
๋ ฅํด์ฃผ์ธ์!');
}
});
์์์ ์ธ๊ธํ ๋๋ก, add-btn์ ํด๋ฆญํ ๋ค์ ํญ๋ชฉ์ด ์ถ๊ฐ๋๊ณ ์๋ ๋ชจ์ต์ด๋ค.
์ด ์ด๋ฒคํธ๋ก ์คํ๋๋ ํจ์์๋ todoList์ ์์ ๋ชฉ๋ก๋ค์ ๋ชจ๋ ์ถ๊ฐํด์ฃผ๋ ์ฝ๋๊ฐ ๋ค ๋ด๊ฒจ์๊ธฐ ๋๋ฌธ์, ๋ก์ปฌ ์คํ ๋ฆฌ์ง์ ์ ์ฅ๋ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ถ๋ ฅ ํ๊ธฐ ์ํด์๋ ํด๋น ๋ด์ฉ์ด ๊ฑฐ์ ๋ค ํ์ํ๋ค.
์ด ๋ด์ฉ์ ๋ด์ ํจ์๋ฅผ ์๋ก ์์ฑํ์ฌ addBtn์ ํด๋ฆญํ ๋, ๋ ๋ฐ์ดํฐ๋ค์ ๋ถ๋ฌ์ฌ ๋ ํด๋น ํจ์๋ฅผ ํธ์ถํ๋๋ก ์์ ํ๋ค.
์์ ํ
// local Storage์์ ๋ถ๋ฌ์ค๊ธฐ
const todoStorage = JSON.parse(localStorage.getItem("todoStorage"));
if (todoStorage !== null) {
for (let i = 0; i < todoStorage.length; i++) {
// todoStorage์ [i]๋ฒ์งธ ๊ฐ์ makeToDoList์ ๋ฃ์ด๋
makeToDoList(todoStorage[i]);
}
}
// add-btn ๋ฒํผ ํด๋ฆญ ์ ์ด๋ฒคํธ
addBtn.addEventListener("click", function () {
if (todoInput.value.trim() !== "") {
makeToDoList();
} else {
alert('๋ด์ฉ์ ์
๋ ฅํด์ฃผ์ธ์.');
}
});
// ๋ฆฌ์คํธ ์ถ๋ ฅ ํจ์
function makeToDoList(storageList) {
const li = document.createElement("li");
// local storage์ ์ ์ฅ๋์ด ์๋ค๋ฉด
if (storageList) {
todoInput.value = storageList.contents;
if (storageList.check === true) {
li.classList.add("checked");
checkBtn.checked = true;
}
}
// .....์๋ต......
todoList.append(li);
}
๊ณต๋ฐฑ ์ ๋ ฅ ์ ํ ์ผ์ด ์ถ๊ฐ ๋์ง ์๋๋ก ํ๋ if else๋ฌธ์ addBtn ํด๋ฆญ ์์ ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ด์ ์์ฑํ๊ณ , ๋๋จธ์ง๋ ๋ชจ๋ makeToDoList ํจ์์ ๋ค์ด์์ด ํธ์ถํ๋ฉด ์ธ์ ๋ ์ง ์ธ ์ ์๊ฒ ๋๋ค.
๋ค๋ง ์ด์ ๊ณผ ๋ฌ๋ฆฌ ํจ์์ ํ๋ผ๋ฏธํฐ storageList๊ฐ ์๊ฒผ๋๋ฐ, ์์ผ๋ฉด if(storageList){}๊ฐ ์คํ๋์ง ์๋๋ค.
* if(storageList) : storageList๊ฐ 1 ์ด์์ธ์ง(์ฆ true์ธ์ง)๋ฅผ ์กฐ๊ฑด์ผ๋ก ํ๊ณ ์์ผ๋ฉฐ, ์๋ค๋ฉด false๊ฐ ๋์ด ๋๋จธ์ง ๋ถ๋ถ์ด ์คํ๋๋ค.
local Storage์์ ์ ์ฅ๋ ํํ๋ key๊ฐ todoStorage์ value๊ฐ {'ํ ์ผ(contents)', '์ฒดํฌ ์ ๋ฌด(check)'}์ ํํ์ ์์๋ก ์ด๋ฃจ์ด์ง ๋ฐฐ์ด๋ก ๋ค์ด๊ฐ ์๋ค.
์ด ๋ ๋ฐฐ์ด์ ์๋ ๊ฐ์ ๋ชจ๋ ์ถ๋ ฅํ๊ธฐ ์ํด for๋ฌธ ์์ makeToDoList() ๋ฉ์๋์ todoStorage[i]๋ฅผ ์ธ์๋ก ๋ฃ์ด ์ฃผ๊ณ ์๊ธฐ ๋๋ฌธ์ if (storageList) {} ๋ถ๋ถ์ด ์คํ๋๋ค. ์ด ๋ if๋ฌธ ๋ด์ ์๋ if (storageList.check === true) {} ์ ๋ํด์๋ ์๋ 2. ์ฒดํฌ๋ฐ์ค์ ์์ ํ๋ค.
* local storage ๊ฐ๋ ์ฐธ๊ณ
Mdn : https://developer.mozilla.org/ko/docs/Web/API/Window/localStorage
๋งน์๋์ ๋ธ๋ก๊ทธ : https://myeongsu0257.tistory.com/130
๊ทธ ์ธ์๋ 2๋ ์ ์ ๊ฐ์ ๋ค์ด๋ณด๋ฉด์ local storage๋ฅผ ํ์ฉํด Todo list๋ฅผ ๋ง๋ค์ด๋ณด๋ ์ค์ต์ ํ์๋๋ฐ ๊ฐ์ ํฌ๋ ๋ฆฌ์คํธ์ธ๋งํผ ์ ์ฌํ ์ ์ด ๋ง์ ๋งํฌ๋ฅผ ๋จ๊ฒจ๋๋ค.
todo list ๊ธฐ๋ณธ ๊ธฐ๋ฅ + local storage์ ์ ์ฅ(์ถ๊ฐํ๋ฉด ๋ฐ๋ก ์ ์ฅ์ด ๋จ) ๋ฐ ์ถ๋ ฅ : https://hydeveloper.tistory.com/71
todo list local storage์์๋ ํ ์ผ ์ญ์ : https://hydeveloper.tistory.com/72
2. ๋ก์ปฌ ์คํ ๋ฆฌ์ง ์ ์ฅ
์ฃผ์์ผ๋ก๋ ๋ฉ๋ชจํด๋๊ณ ์ ์ฅ ๊ธฐ๋ฅ ๋ํ ์ด ๊ธ์์ ๋ค๋ค๊ธฐ ๋๋ฌธ์ ์์ธํ ์ค๋ช ์ ํจ์คํ๋ค...
// ใ๏ฝฅ๏พ*๏ฝก๏ฝฅ ๏ฝก*๏ฝฅ๏พ ์ ์ฅํ๊ธฐ ๏ฝฅ๏พ*๏ฝก๏ฝฅ ๏ฝก*๏ฝฅ๏พ
document.getElementById("saveStorage").addEventListener("click", function () {
// localStorage์ ๋ด์ array
const todoStorage = [];
for (let i = 0; i < todoList.children.length; i++) {
const todoObject = {
contents: todoList.children[i].querySelector("span").textContent,
// classList.contains("ํด๋์ค๋ช
") : ํด๋น ํด๋์ค ๋ช
์ด ํด๋น ์์์ ํฌํจ๋์ด์๋์ง
check: todoList.children[i].classList.contains("checked"),
};
todoStorage.push(todoObject);
}
console.log(todoStorage);
// JSON.stringfy() : ๋ณ์๋ฅผ ๋ฌธ์์ด๋ก ๋ฐ๊ฟ array ๊ทธ ์์ฒด๋ฅผ ๋ฌธ์์ด๋ก ๋ง๋ ๋ค.
localStorage.setItem("todoStorage", JSON.stringify(todoStorage));
});
3. ์ฒดํฌ๋ฐ์ค
์์ ์
addBtn.addEventListener('click', function () {
const li = document.createElement('li');
const checkBtn = document.createElement('input');
checkBtn.type = 'checkbox';
li.append(checkBtn);
checkBtn.addEventListener('change', function () {
if (checkBtn.checked) {
this.nextElementSibling.style.textDecoration = 'line-through';
} else {
this.nextElementSibling.style.textDecoration = '';
}
});
});
addBtn์ 'click'์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ ๋ ์ฒดํฌ๋ฐ์ค๊ฐ ์ถ๋ ฅ๋๊ฒ ํ๋ค.
์ด๋ ๋ก์ปฌ ์คํ ๋ฆฌ์ง์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ์ง ์๊ธฐ ๋๋ฌธ์ ๊ทธ๋ฅ ๋จ์ํ ์ฒดํฌ๋ฐ์ค์ ๊ธฐ๋ฅ๋ง ํ๋ ์ ๋๋ค.
์ฒดํฌ๋ฐ์ค์ ์ฒดํฌ ๋ถ๋ถ์ธ checkBtn์ 'change'์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ ๋,
๋ฒํผ์ด ์ฒดํฌ๋๋ค๋ฉด(checkBtn.checked) ์ฒดํฌ๋ฒํผ์ ๋ค์ ์์๊ฐ ๋ spanํ๊ทธ์ ์คํ์ผ์ textDecoration = 'line-through'๋ฅผ ์ถ๊ฐํ์ฌ ์ฒดํฌ๋ ํญ๋ชฉ์ ์ทจ์์ ์ ๊ทธ๋ฆฌ๊ฒ ํ๋ค.
์๋๋ ์์ ํ์ ์ฝ๋๋ค.
// ๋ฆฌ์คํธ ์ถ๋ ฅ ํจ์
function makeToDoList(storageList) {
const li = document.createElement('li');
const checkBtn = document.createElement('input');
// local storage์ ์ ์ฅ๋์ด ์๋ค๋ฉด
if (storageList) {
todoInput.value = storageList.contents;
// ์์ if(storageList)์ฒ๋ผ if(storageList.check)์ผ๋ก ์จ๋ ๋๊ฐ์ด ์๋ํ๋ค
if (storageList.check === true) {
li.classList.add("checked");
checkBtn.checked = true;
}
}
checkBtn.type = 'checkbox';
li.append(checkBtn);
checkBtn.addEventListener('change', function () {
// toggle("ํด๋์ค๋ช
") : ํด๋น ํด๋์ค๊ฐ ์กด์ฌํ๋ค๋ฉด ์ ๊ฑฐ ํ false๋ฅผ ๋ฐํ, ์กด์ฌํ์ง ์์ผ๋ฉด ์ถ๊ฐ ํ true ๋ฐํ
this.parentElement.classList.toggle('checked');
});
}
์ฒดํฌ๋ฒํผ์ ์ถ๊ฐ๋๊ฑฐ๋ ์์ ๋ ๋ด์ฉ์ด ๊ฝค ์๋ค.
1) checkBtn์ ๋๋ ์ ๋์ ์ด๋ฒคํธ ๋ด์ฉ
์์ ์ ์๋ ๋ฐ๋ก ๋ค ํ์ ์์์๊ฒ ์คํ์ผ์ ์ ์ฉํ๋ค๋ฉด, ์ด๋ฒ์ Local Storage์๋ check ์ ๋ฌด๋ฅผ ํ๋ณํด์ผ ํ๋ฏ๋ก ํด๋น ์ฒดํฌ๋ฒํผ์ ๋ถ๋ชจ ์์(li)์๊ฒ checked๋ผ๋ ํด๋์ค๋ฅผ ์ถ๊ฐํ๋ค.
ํด๋์ค๋ฅผ ์ถ๊ฐํ๋ ค๋ฉด add()๋ฉ์๋ ์จ๋ ๋๋๋ฐ toggle()๋ฉ์๋๋ฅผ ์ ์ผ๋
์ฃผ์์ ์ ์ด๋ ๋๋ก, ๋จ ํ์ค๋ก ํด๋น ๋ถ๋ชจ์์์๊ฒ checked๋ผ๋ ํด๋์ค๊ฐ ์ด๋ฏธ ์๋ ์ํ๋ผ๋ฉด checked ํด๋์ค๋ฅผ ์์ ์ฃผ๋ฉฐ, ๋ง์ฝ ์๋ ์ํ๋ผ๋ฉด checked๋ฅผ ์ถ๊ฐํด์ค ์ ์๋ค.
๊ทธ๋ ๋ค๋ฉด ์คํ์ผ์ ์ด๋ป๊ฒ ๋๋, ๊ทธ๊ฑด css ํ์ผ์ ์์ ํ๋ค.
#todo-list li.checked > span {
text-decoration: line-through;
}
์๊น๋ถํฐ ์ ํ์ ์์๋ง ๊พธ๋ฉฐ์ฃผ๋๋ฉด
์ ์ด๋ฏธ์ง์ ๊ฐ์ด ๊ทธ๋ฅ ๋ถ๋ชจ๋ฅผ ๊พธ๋ฉฐ์ค ๊ฒฝ์ฐ, ์์ ์๋ ์ญ์ ๋ฒํผ๊น์ง ๋ฐ์ค์ด ๊ทธ์ด์ง๋๋ฐ ๋ณด๊ธฐ๊ฐ ์์ข์์ span ํ๊ทธ๋ง ๊พธ๋ฉฐ์ฃผ๊ณ ์๋ค...
2) if (storageList.check === true) {}
์์ 1. ์์ ์ถ๊ฐ๋ if(storageList){}๋ฌธ ์์ ์๋ ์กฐ๊ฑด์ด๋ค. ๋ชฉ๋ก์ ์ถ๋ ฅํ ๋ ๊ธฐ์กด์ ์ ์ฅ๋์ด์๋ storageList value์ ๋ด๊ธด ๋ฐฐ์ด์ ์์๊ฐ {contents, check}์ ํํ๋ฅผ ๊ฐ์ง๊ณ ์๋ค๊ณ ์ธ๊ธํ์๋๋ฐ, ์ด ๋ check์ ๊ฐ์ booleanํ์ผ๋ก ๋ฐ์๋ค.
๋๋ฌธ์ check๊ฐ true๋ผ๋ฉด ํด๋น li์ checked ํด๋์ค๋ฅผ ์ถ๊ฐํด์ฃผ๋๋ฐ, ๋ฌธ์ ๋ ์์ 1)์์ ์ธ๊ธํ ์ด๋ฒคํธ์๋ ๋ฌ๋ฆฌ ์ง๊ธ ํด๋น li ์์ ์๋ checkBtn์ ์ง์ ์ ์ผ๋ก ์ ๊ทผํ๋ ๊ฒ์ด ์๋๊ธฐ ๋๋ฌธ์ checkBtn.checked = true;๋ฅผ ์ถ๊ฐํด ํด๋น li์ ์ฒดํฌ๋ฐ์ค์ checked ์์ฑ์ true๋ก ํด์ฃผ๋ ๊ฒ์ด๋ค.
์ฐธ๊ณ
local storage์์ ๋ฆฌ์คํธ ๋ถ๋ฌ์ค๋ ๊ณผ์ ์ https://velog.io/@seoyaon/Javascript-Todo-List-%EB%A7%8C%EB%93%A4%EA%B8%B0 ์ ๋ณด๊ณ ๋ง์ด ์ฐธ๊ณ ํ๋ค... ์ง์ง๊ฐ์ฌํฉ๋๋ค
'javascript' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
javascript/์์ ๋ณต์ฌ์ ๊น์ ๋ณต์ฌ (0) | 2025.03.20 |
---|---|
javascript/chart.js๋ก ๊ทธ๋ํ ๋ง๋ค๊ธฐ (0) | 2025.03.19 |
250313 to-do ๋ฆฌ์คํธ ๋ง๋ค๊ธฐ (2) (0) | 2025.03.14 |
javascript/var๋ฅผ ๋์ด์ ์ฌ์ฉํ์ง ์๋ ์ด์ (2) | 2025.03.12 |
250307 ํ๋ก๊ทธ๋๋จธ์ค (0) | 2025.03.07 |