JavaScript/Nomad Coders
[TIL] ๐ก Day 10 - JavaScript๋ก TodoList ๋ง๋ค๊ธฐ
vividmin
2022. 5. 1. 03:08
320x100
โ ์ด ํฌ์คํ ์ ๋ ธ๋ง๋์ฝ๋ - "๋ฐ๋๋ผ JS๋ก ํฌ๋กฌ ์ฑ ๋ง๋ค๊ธฐ๋ฅผ ๋ค์ผ๋ฉด์ ๊นํ๋ธ์ ๊ธฐ๋กํ ํ๊ธฐ๋ฅผ ์ฎ๊ธด ๋ด์ฉ์ ๋๋ค.
๋ชฉํ : ๐ JavaScript๋ก Todo List ๋ง๋ค๊ธฐ
๐ฑ Todo List ๊ธฐ๋ณธ ํ ์ค๋น
๐ ์ผ๋จ ํ์ํ ์์๋ค์ ์ด๋ค ๊ฒ์ด ์๋์ง ์์๋ณด์.
- Form : ์ฌ์ฉ์๊ฐ todo ์ ๋ ฅ → ์ ์ถํ๋ ํํ๊ฐ ํ์ํ๋ค.
- List : ์ ๋ ฅํ todo๋ฅผ ๋์ดํด์ผ ๋๋ค.
- input : ์ฌ์ฉ์์๊ฒ todo๋ฅผ ์ ๋ ฅ๋ฐ์์ผ ํ๋ค.
- ์์ ์ฝ๋
<form id="todo-form">
<input type="text" placeholder="Write a To Do and Press Enter" required />
</form>
<ul id="todo-list"></ul>
const toDoForm = document.getElementById("todo-form");
const toDoInput = document.querySelector("#todo-form input");
const toDoList = document.getElementById("todo-list");
function paintToDo(newTodo) {
const li = document.createElement("li");
const span = document.createElement("span");
li.appendChild(span);
span.innerText = newTodo;
toDoList.appendChild(li);
}
function handleToDoSubmit(event) {
event.preventDefault();
const newTodo = toDoInput.value;
toDoInput.value = "";
paintToDo(newTodo);
}
toDoForm.addEventListener("submit", handleToDoSubmit);
- ์ฃผ๋ชฉํ ๋งํ ์ฝ๋
// ๋์ค์ button๋ ์ถ๊ฐํ๊ธฐ ์ํด์ span์ผ๋ก ๋ง๋ ๋ค
li.appendChild(span);
/** ToDo๋ ์
๋ ฅ๋ฐ์ value๋๋ก ๊ฐ๊ฐ ํ ์ค์ฉ ์กด์ฌํ๋ค.
input์ ํ์ฌ value๋ฅผ ์๋ก์ด ๋ณ์์ ๋ณต์ฌํ๊ณ ์๋ค.
๋ณต์ฌ ํ ๊ฒ์ด๋ฏ๋ก ๋ค์์ input์ ๋ญํด๋ ์๋ฌด ์ง์ฅ์ด ์๋ค.
*/
const newTodo = toDoInput.value;
// todo Input์ ๋น์ด ์๋ ์ํ๋ก ๋ง๋ค์ด ์ค๋ค.
toDoInput.value = "";
// paintToDo์ newTodo๋ฅผ ์ธ์๋ก ์ฃผ๋ฉด์ ํธ์ถํ๋ค.
paintToDo(newTodo);
- ๊ทธ ์ธ ํด๊ฒฐ์ฌํญ
- form์ด submit ํ ์๋ก๊ณ ์นจ ๋์ง ์๋๋ก ๊ธฐ๋ณธ ๋์ ๋ง๊ธฐ ๐๐ป preventDefault( ) ์ฌ์ฉ
- todo๋ฅผ ์ง์ฐ๋ ๋ฒํผ๋ ๋ง๋ค์ด ๋ณด์.
- ์๋ก๊ณ ์นจ ๋ค์๋ ์ ๋ ฅํ todo๊ฐ ์ฌ๋ผ์ง์ง ์๋๋ก ๋ง๋ค์.
๐ฑ Delete ToDos
๐ todo ์ญ์ ๋ฒํผ ๋ง๋ค๊ธฐ
- ์กฐ๊ฑด
- ์ด ๋ฒํผ์ event๋ฅผ ์์ ํด์ผ ํ๋ค.
- append๋ ๋ง์ง๋ง์ ๋ฃ์ด์ฃผ์ด์ผ ํ๋ค.
("todo list + ์ญ์ ๋ฒํผ"์ด ๋ฆฌ์คํธ์ ํ ์์ด๋ค. ๊ฐ์ ๋ค ๋ง๋ ํ li์ append!)
- ์ญ์ ๋ฒํผ ๋ง๋ค๊ธฐ
- ๋ฒํผ ํ๊ทธ ๋ง๋ค๊ธฐ → ์์ ๋ค์ด๊ฐ ์์ ๋ฃ๊ธฐ (del or โ) → ์ด๋ฒคํธ ์์ ํ ์ ์๊ฒ ์ค์
function paintToDo(newTodo) {
const li = document.createElement("li");
const span = document.createElement("span");
span.innerText = newTodo;
const button = document.createElement("button"); //button ๋ง๋ค๊ธฐ
button.innerText = "โ"; // button ์์ x ์ด๋ชจํฐ์ฝ ๋ฃ๊ธฐ
button.addEventListener("click", deleteToDo); // ๋ฒํผ ์ด๋ฒคํธ ์์
li.appendChild(span);
li.appendChild(button);
toDoList.appendChild(li);
}
- ์์๋ฅผ ์ญ์ ํ๋ deleteToDo ํจ์ ๋ง๋ค๊ธฐ
- ์ฌ๋ฌ ๊ฐ์ todo ์ค์ ์ด๋ค ๊ฒ์ ์ง์์ผ ํ ์ง ์์์ผ ํ๋ค.
- click์ด๋ฒคํธ๋ฅผ console๋ก ํ์ธํด๋ณด๋ฉด Path์์ ๋ฒํผ์ด li์ ํฌํจ๋์ด ์๋ ๊ฒ์ ์ ์ ์๋ค.
- deleteToDo ์ฝ๋
function deleteToDo(event) {
const li = event.target.parentElement;
li.remove();
}
๐ฑ Save ToDos
๐ ์๋ก๊ณ ์นจํด๋ ์ฌ๋ผ์ง์ง ์๋๋ก ์ ์ฅํ๊ธฐ.
- toDos๋ผ๋ ์ด๋ฆ์ ๋น ๋ฐฐ์ด ์ ์ธํ๊ธฐ
const toDos = [];
- ์๋ก์ด todo๊ฐ ์๊ธฐ๋ฉด toDos ๋ฐฐ์ด์ ์ถ๊ฐ๋๋๋ก ์ค์
toDos.push(newTodo);
- localStorage์ toDos[] ์ ์ฅํ๋ ํจ์ ๋ง๋ค๊ธฐ
(์ง๋๋ฒ greeting์ฒ๋ผ string ํํ๋ก ์ ์ฅํด์ผ ํ๋ค.)
function saveToDos() {
localStorage.setItem("todos", JSON.stringify(toDos));
}
- paintToDo(newTodo) ๋ค์ saveToDos ํธ์ถํ๊ธฐ
saveToDos();
- ์ต์ข ์ฝ๋
const toDos = [];
function saveToDos() {
localStorage.setItem("todos", JSON.stringify(toDos));
}
function handleToDoSubmit(event) {
event.preventDefault();
const newTodo = toDoInput.value;
toDoInput.value = "";
toDos.push(newTodo);
paintToDo(newTodo);
saveToDos();
}
๐ฑ loading Todos
๐ localStrage์ ์ ์ฅ๋ todo list ๊ฐ์ ธ์ค๊ธฐ
- ํ์ฌ๋ localStorage์๋ ์ ์ฅ๋์ด ์์ง๋ง, ํ๋ฉด์๋ ๋ณด์ด์ง ์๋ ์ํ์ด๋ค.
- localStorage์ ์๋ string์ array๋ก ๋ค์ ๋ณํ.
- string ๊ฐ์ ธ์ค๊ธฐ → localStorage.getItem( ) ์ฌ์ฉ
- todos๋ฅผ ์ฌ๋ฌ ๋ฒ ์ฐ๋๊น ์ค์๋ฅผ ์ค์ด๊ธฐ ์ํด์ ๋ณ์๋ก ์ ์ธ.
- const TODOS_KEY = "todos";
- savedToDos๊ฐ null์ผ ๊ฐ๋ฅ์ฑ ๊ณ ๋ คํด์ผ ํจ.
- forEach ์ฌ์ฉํด์ ๊ฐ list ํ๋ฉด์ ๋ฟ๋ ค์ฃผ๊ธฐ.
- js๋ array์ ์๋ ๊ฐ๊ฐ์ item์ ๋ํด fuction์ ์คํํ ์ ์๊ฒ ํด ์ค๋ค.
- parsedToDos๋ ๋ฐฐ์ด์ด๋ฏ๋ก, forEach๋ผ๋ ๊ฒ์ ๊ฐ์ง๊ณ ์๋ค.
forEach๋ item์ ๋ํด ํจ์๋ฅผ ์คํํ ์ ์๊ฒ ํด ์ค๋ค.
- ๐ก JS Tip!
- 1๋ฒ, 2๋ฒ ๋ฐฉ๋ฒ์ ๋์ผํ ํํ๋ฒ์ด๋ค.
- 2๋ฒ : ํ์ดํ ํจ์ ์ฌ์ฉ๋ฐฉ๋ฒ
// 1๋ฒ
function sayHello(item) {
console.log("this is the turn of", item)
}
parsedToDos.forEach(sayHello);
// 2๋ฒ
parsedToDos.forEach((item) => console.log("this is the turn of ", item));
- ์ฐ๋ฆฌ๋ ์ด๋ฏธ todo list๋ฅผ ๊ทธ๋ฆฌ๋ paintToDo( )๊ฐ ์๋ค.
- paintToDo๋ newItem์ด๋ผ๋ ์ธ์๊ฐ ํ์ํ๋ฐ ์ด ์ธ์๊ฐ ๊ณง localStorage์์ ๊ฐ์ ธ์จ parsedTodo์ด๋ฏ๋ก
๊ทธ๋ฅ paintToDo๋ง forEach์ ๋ฃ์ด์ฃผ๋ฉด ๋๋ค.
- paintToDo๋ newItem์ด๋ผ๋ ์ธ์๊ฐ ํ์ํ๋ฐ ์ด ์ธ์๊ฐ ๊ณง localStorage์์ ๊ฐ์ ธ์จ parsedTodo์ด๋ฏ๋ก
- loading Todos ์ฝ๋
const TODOS_KEY = "todos";
const savedToDos = localStorage.getItem(TODOS_KEY);
if (savedToDos !== null) {
const parsedToDos = JSON.parse(savedToDos);
parsedToDos.forEach(paintToDo);
}
- ์ฌ๊ธฐ๊น์ง ํ์ ๋ ๋ฌธ์ ์ โ
- ์ด ์ํ๋ ์๋ก ์ ์ฅ๋ list๋ง localStorage์ ์ ์ฅํ๊ณ ์ด์ ๊ฒ์ ์ง์๋ฒ๋ฆฐ๋ค.
- ์ด์ ?
- ์์ ์ ํญ์ ๋น์ด์๋ [ ]์ด๋ผ์ paintToDo๋ฅผ ํธ์ถํ ๋๋ง๋ค ๊ฐ์ ๋ฎ์ด์ฐ๊ธฐ ํ๋ค.
const toDos = [];
-
- ํด๊ฒฐ๋ฐฉ์
- let์ผ๋ก ๋ฐ๊ฟ์ ์ ๋ฐ์ดํธ ๊ฐ๋ฅํ๋๋ก ์ค์
- localStorage์ ์ด์ list๊ฐ ์์ผ๋ฉด toDos์ parsedToDos๋ฅผ ๋ฃ์ด์ ์ ์ toDo๋ฅผ ๋ณต์.
- ํด๊ฒฐ๋ฐฉ์
- ์์ ๋ ์ฝ๋
let toDos = [];
if (savedToDos !== null) {
const parsedToDos = JSON.parse(savedToDos);
toDos = parsedToDos;
parsedToDos.forEach(paintToDo);
}
- ์ถ๊ฐ๋ก ํด๊ฒฐํ ๋ฌธ์ โ
- delete๋ฅผ ํด๋ ์๋ก๊ณ ์นจ ํ๋ฉด ์ด์๋๋ค.
- localStorage์์ ์ญ์ ๊ฐ ์ ๋์๊ธฐ ๋๋ฌธ์ด๋ค. ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํด๋ณด์.
๐ฑ Delete Todos 2
๐ ์ญ์ ๋ฒํผ ๋๋ฅด๋ฉด localStrage์์๋ ์ญ์ ๋๋๋ก ๋ง๋ค๊ธฐ.
- ์ด๋ค todos text๊ฐ ์ง์์ง๋์ง ์์์ผ ํ๋ค.
- todos๋ฅผ ๋ง๋ค ๋ id๋ฅผ ์ฃผ๋๋ก ๋ง๋ค์
- ๋๋ค id ๋ง๋ค๊ธฐ -> Date.now() ์ฌ์ฉ (todo๊ฐ ๋ง๋ค์ด์ง ๋์ ๋ ์ง์ ์๊ฐ)
- ์ด์ : ์ฌ์ฉ์๊ฐ ์ ์ด๋ text๋ฅผ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ก push
- ํ์ฌ : object๋ฅผ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ก push
function handleToDoSubmit(event) {
event.preventDefault();
const newTodo = toDoInput.value;
const newTodoObj = {
text: newTodo,
id: Date.now(),
};
toDos.push(newTodoObj);
paintToDo(newTodoObj);
saveToDos();
}
- newToDoObj๊ฐ ๋์ผ๋๊น paintTodo์ ๋ด์ฉ์ ์กฐ๊ธ ๋ณ๊ฒฝํด์ฃผ์ด์ผ ํ๋ค.
function paintToDo(newTodo) {
const li = document.createElement("li");
// ๊ฐ list์ id๊ฐ์ ์ค๋ค.
li.id = newTodo.id;
const span = document.createElement("span");
// ์ด๋ ๊ฒ ํด์ฃผ์ง ์์ผ๋ฉด ํ๋ฉด์ objectํํ๋ก ํ์๋๋ค.
span.innerText = newTodo.text;
const button = document.createElement("button");
button.innerText = "โ";
button.addEventListener("click", deleteToDo);
li.appendChild(span);
li.appendChild(button);
toDoList.appendChild(li);
}
- ์ด์ x ๋ฒํผ์ ๋๋ฅผ ๋ ๊ทธ list์ id๋ฅผ ์ป์ ์ ์์ผ๋ฉด localStorage์์๋ ์ญ์ ๊ฐ ๊ฐ๋ฅ
- array์์ element ์ญ์ ํ๋ ๋ฐฉ๋ฒ?
๐๐ป filter ์ฌ์ฉ- ์ค์ ๋ก element๋ฅผ array์์ ์ง์ฐ๋ ๊ฒ์ด ์๋๋ผ ์ง์ฐ๊ณ ์ถ์ item์ ๋นผ๊ณ ์ array๋ฅผ ๋ง๋ ๋ค. (๋งค์ฐ ์ค์โจ)
- filter(ํจ์)์ ํํ๋ก ์ฌ์ฉ
- filter๋ forEach์ฒ๋ผ ๊ฐ item์ ๋ฃ์ด์ ํจ์๋ฅผ ํธ์ถํ๋ค.
- array์ item์ ์ ์งํ๊ณ ์ถ๋ค๋ฉด filter์์ ํจ์๋ ๋ฐ๋์ true๋ฅผ ๋ฆฌํดํด์ผ๋ง ํ๋ค.
- false๋ฅผ ๋ฆฌํดํ๋ค๋ฉด ์ array์ false๋ฅผ ๋ฆฌํดํ item์ ๋ค์ด๊ฐ์ง ์๋๋ค.
- ์ด ๊ฐ๋
์ผ๋ก localStorage์์๋ ์ญ์ ๋๋๋ก ๋ง๋ค์ด๋ณด์.
- ๋ฒํผ์ ํด๋ฆญํ ๋๋ง๋ค list์ id๋ฅผ ์ป์ ์ ์๋ค.
- array์ ์๋ item์ id!== ํด๋ฆญ๋ id => ์ array์ ์ถ๊ฐ๋๋๋ก filter๋ฅผ ์ค์
toDos = toDos.filter((toDo) => toDo.id !== li.id);
- ๊ทธ๋ฐ๋ฐ ์ฌ๊ธฐ๊น์ง ํ๋ฉด ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค.
๐๐ป ๋ณ์์ type ๋๋ฌธ์ ์ ๋๋ก ๋์ํ์ง โ- li์ id๋ string, ์ด๊ฒ์ number๋ก ๋ฐ๊พธ์ด์ฃผ์ด์ผ ํ๋ค.
- ๊ทธ๋ค์ ์๋ก ๋ง๋ค์ด์ง array๋ฅผ toDos์ ์ ๋ฐ์ดํธํด์ค๋ค.
toDos = toDos.filter((toDo) => toDo.id !== parseInt(li.id));
saveToDos();
๐ฑ Todo List ์์ฑ ๋ฒ์
๐ ์ ์ฒด์ ์ผ๋ก ํด๊ฒฐ ๋ฐฉ์์ด ์ ์ฉ๋ ์ฝ๋
- html ์ฝ๋
<form id="todo-form">
<input type="text" placeholder="Write a To Do and Press Enter" required />
</form>
<ul id="todo-list"></ul>
- js ์ฝ๋
const toDoForm = document.getElementById("todo-form");
const toDoInput = document.querySelector("#todo-form input");
const toDoList = document.getElementById("todo-list");
const TODOS_KEY = "todos";
let toDos = [];
function saveToDos() {
localStorage.setItem(TODOS_KEY, JSON.stringify(toDos));
}
function deleteToDo(event) {
const li = event.target.parentElement;
li.remove();
toDos = toDos.filter((toDo) => toDo.id !== parseInt(li.id));
saveToDos();
}
function handleToDoSubmit(event) {
event.preventDefault();
const newTodo = toDoInput.value;
toDoInput.value = "";
const newTodoObj = {
text: newTodo,
id: Date.now(),
};
toDos.push(newTodoObj);
paintToDo(newTodoObj);
saveToDos();
}
function paintToDo(newTodo) {
const li = document.createElement("li");
li.id = newTodo.id;
const span = document.createElement("span");
span.innerText = newTodo.text;
const button = document.createElement("button");
button.innerText = "โ";
button.addEventListener("click", deleteToDo);
li.appendChild(span);
li.appendChild(button);
toDoList.appendChild(li);
}
toDoForm.addEventListener("submit", handleToDoSubmit);
const savedToDos = localStorage.getItem(TODOS_KEY);
if (savedToDos !== null) {
const parsedToDos = JSON.parse(savedToDos);
toDos = parsedToDos;
parsedToDos.forEach(paintToDo);
}
๋ฐ์ํ