[JS ES6] To-do list (+localStorage)

choii_iiยท2025๋…„ 3์›” 26์ผ

[JS ES6] ์Šคํ„ฐ๋””๋…ธํŠธ

๋ชฉ๋ก ๋ณด๊ธฐ
6/6

To-do list

๐Ÿ“Œ KEY POINT

๐Ÿ’š ๋ฆฌ์ŠคํŠธ ๋“ฑ๋ก ์‹œ, ์ž…๋ ฅํ•œ input value๊ฐ’์„ ๊ทธ๋Œ€๋กœ ๋ฆฌ์ŠคํŠธ์— ์ถ”๊ฐ€
๐Ÿ’š ๋ฆฌ์ŠคํŠธ ์‚ญ์ œ ์‹œ, ์„ ํƒํ•œ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ฐพ์•„ ์‚ญ์ œํ•ด์•ผํ•˜๋Š” ๋กœ์ง
๐Ÿ’š createElement()์™€ append() ๋ฉ”์„œ๋“œ๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์Šคํฌ๋ฆฝํŠธ๋กœ DOM ์š”์†Œ ์ƒ์„ฑ
๐Ÿ’š ์„ ํƒํ•œ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋งค์นญ ์‹œํ‚ค๊ธฐ ์œ„ํ•ด id๊ฐ’์œผ๋กœ ๊ตฌ๋ถ„์ด ํ•„์š” (Date.now()๋ผ๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜ ์‚ฌ์šฉ)
๐Ÿ’š filter ์†์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ id ๊ฐ’์ด ๋งค์นญ๋˜๋Š” ๋ฆฌ์ŠคํŠธ ๊ตฌ๋ถ„
๐Ÿ’š localStorage์— ํ…์ŠคํŠธ ํƒ€์ž…์œผ๋กœ ์ €์žฅ์‹œํ‚ค๊ธฐ ์œ„ํ•ด JSON.stringify() ์†์„ฑ ์‚ฌ์šฉ
๐Ÿ’š ํ…์ŠคํŠธ ํƒ€์ž…์œผ๋กœ ์ €์žฅ๋œ localStorage ๋ฐ์ดํ„ฐ ๊ฐ’์„ ๋‹ค์‹œ ๋ฐฐ์—ด๋กœ ์ €์žฅ์‹œํ‚ค๊ธฐ ์œ„ํ•ด JSON.parse() ์†์„ฑ ์‚ฌ์šฉ


๐Ÿ‘‰๐Ÿป ๋งˆํฌ์—…์€ ์ด๋ ‡๊ฒŒ! (HTML5)

๐Ÿฉต ํ…์ŠคํŠธ๋ฅผ ์ž…๋ ฅํ•  input ํผ ์ƒ์„ฑ

๐Ÿฉต ์ €์žฅ๋œ list๋ฅผ ๋…ธ์ถœ ์‹œํ‚ฌ ๋ฆฌ์ŠคํŠธ ์˜์—ญ ์ƒ์„ฑ

<body>
 <form id="todo-form">
	<input type="text" placeholder="Write a To Do and Press Enter" required>
 </form>
 <ul id="todo-list"></ul>
</body>

๐Ÿ‘‰๐Ÿป ์Šคํฌ๋ฆฝํŠธ๋Š” ์ด๋ ‡๊ฒŒ! (JS ES6)

1๏ธโƒฃ paintTodo() ํ•จ์ˆ˜ ์‹คํ–‰

๐Ÿฉต To-do list์— ์ƒˆ๋กœ์šด ํ•ญ๋ชฉ์„ ์ถ”๊ฐ€
๐Ÿ”น ๋“ฑ๋ก๋œ ๋ฆฌ์ŠคํŠธ๋Š” li > span + button ๊ตฌ์กฐ๋กœ ๋งˆํฌ์—…๋˜๋„๋ก createElement ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉ

<script>
function paintTodo(newTodo){
    // ์ „๋‹ฌ๋ฐ›์„ newTodo๋Š” handleTodoSubmitํ•จ์ˆ˜์—์„œ ์‹คํ–‰์‹œํ‚จ todoInput.value๊ฐ’์„ ์˜๋ฏธ

    const li = document.createElement("li");
    li.id = newTodo.id;

    const span = document.createElement("span");
    span.innerText = newTodo.text;

    const deleteBtn = document.createElement("button");
    deleteBtn.innerText = "โŒ";
    deleteBtn.addEventListener("click", deleteTodo);

    li.append(span);
    li.append(deleteBtn);
    todoList.append(li);
}
</script>

2๏ธโƒฃ handleTodoSubmit() ํ•จ์ˆ˜ ์‹คํ–‰

๐Ÿฉต input์ด submit๋˜๋ฉด handleTodoSubmit() ํ•จ์ˆ˜ ์‹คํ–‰
๐Ÿ”น ์ž…๋ ฅํ•œ value ๊ฐ’์„ newTodo ๋ณ€์ˆ˜์— ์ €์žฅ (๋ฆฌ์ŠคํŠธ์— value ๊ฐ’์„ ๋…ธ์ถœ์‹œ์ผœ์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ)
๐Ÿ”น input์ด submit๋˜๋ฉด value ๊ฐ’์„ ๊ณต๋ฐฑ์œผ๋กœ ๋ฆฌ์…‹
๐Ÿ”น ๋“ฑ๋กํ•œ ๋ฆฌ์ŠคํŠธ(text)๋ฅผ newTodoObj ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ todos ๋ฐฐ์—ด์— ์ถ”๊ฐ€
๐Ÿ”น id๋Š” ๋ฆฌ์ŠคํŠธ ์‚ญ์ œ ์‹œ, ํด๋ฆญํ•œ ๋ฆฌ์ŠคํŠธ์™€ ๋งค์นญ ์‹œ์ผœ์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ž„์˜๋กœ Date.now(๋“ฑ๋ก์‹œ๊ฐ„) ๊ฐ’์„ ๋ถ€์—ฌ
๐Ÿ”น paintTodo()ํ•จ์ˆ˜ ์‹คํ–‰ ์‹œ, ์ธ์ˆ˜๋กœ newTodoObj๋ฅผ ์ถ”๊ฐ€ (=์ƒˆ๋กœ์šด ํ•  ์ผ ์ถ”๊ฐ€)
๐Ÿ”น saveTodos()๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ localStorage์— ์ €์žฅ

<script>
function handleTodoSubmit(event){
    event.preventDefault();
    
    const newTodo = todoInput.value;
    todoInput.value = ""; // ์ž…๋ ฅ ํ›„ ๊ณต๋ฐฑ์œผ๋กœ ์—…๋ฐ์ดํŠธ

    //newTodo๋ฅผ todos์— ๋ฐฐ์—ด(array)๋กœ ์ €์žฅ
    const newTodoObj = {
        text:newTodo,
        id:Date.now(),
    }
    todos.push(newTodoObj);

    paintTodo(newTodoObj);  // todos ๋ฐฐ์—ด์„ list๋กœ ์ƒ์„ฑ
    saveTodos();
}

todoForm.addEventListener("submit", handleTodoSubmit);
</script>

3๏ธโƒฃ deleteTodo() ํ•จ์ˆ˜ ์‹คํ–‰

๐Ÿฉต ์‚ญ์ œ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด deleteTodo() ํ•จ์ˆ˜ ์‹คํ–‰ (=๋ฆฌ์ŠคํŠธ ์‚ญ์ œ)
๐Ÿ”น handleTodoSubmit()ํ•จ์ˆ˜์—์„œ๋Š” id๋Š” ๋ฆฌ์ŠคํŠธ ์‚ญ์ œ ์‹œ, ํด๋ฆญํ•œ ๋ฆฌ์ŠคํŠธ์™€ ๋งค์นญ ์‹œ์ผœ์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ž„์˜๋กœ Date.now(๋“ฑ๋ก์‹œ๊ฐ„) ๊ฐ’์„ ๋ถ€์—ฌํ–ˆ์—ˆ๋‹ค.
๐Ÿ”น ํด๋ฆญํ•œ ๋ฆฌ์ŠคํŠธ์˜ ๋ถ€๋ชจ์š”์†Œ๋ฅผ li๋ผ๋Š” ๋ณ€์ˆ˜์— ์ €์žฅ
๐Ÿ”น todos ๋ฐฐ์—ด ์ค‘ filter ์†์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ todo.id๊ฐ’๊ณผ li.id๊ฐ’์ด ๋‹ค๋ฅธ ๋ฆฌ์ŠคํŠธ๋งŒ todos์— ์ €์žฅ (์ฆ‰, ์‚ญ์ œ๋ฒ„ํŠผ์„ ํด๋ฆญํ•œ ํ•ด๋‹น li์˜ id์™€ ์ผ์น˜ํ•˜๋Š” ํ•ญ๋ชฉ์„ ์ œ์™ธํ•˜๊ณ  ๋‚˜๋จธ์ง€ ํ•  ์ผ๋งŒ ๋‚จ๊น€)
๐Ÿ”น saveTodos()๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋ณ€๊ฒฝ๋œ ๋ชฉ๋ก์„ ์ €์žฅ

<script>
function deleteTodo(event){
    // console.log("delete click!");
    const li = event.target.parentElement;
    // event(ํด๋ฆญ)๋Œ€์ƒ์˜ ๋ถ€๋ชจ์š”์†Œ

    todos = todos.filter(function(todo){
        return todo.id !== parseInt(li.id);
    })
    li.remove();
    // console.log(li.id);
    saveTodos();
};
</script>

4๏ธโƒฃ saveTodos() ํ•จ์ˆ˜ ์‹คํ–‰

๐Ÿฉต ๋ฆฌ์ŠคํŠธ๋ฅผ ์˜๊ตฌ์ ์œผ๋กœ localStorage์— ์ €์žฅ์‹œํ‚ค๊ธฐ ์œ„ํ•œ ํ•จ์ˆ˜
๐Ÿ”น localStorage.setItem()์„ ์‚ฌ์šฉํ•˜์—ฌ todos ๋ฐฐ์—ด์„ ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜ํ•œ ํ›„ ์ €์žฅ. (๋ฐฐ์—ด์€ JSON.stringify()๋ฅผ ์‚ฌ์šฉํ•ด ํ…์ŠคํŠธ๋กœ ๋ณ€ํ™˜)

<script>
function saveTodos(){
    localStorage.setItem(TODOS_KEY, JSON.stringify(todos)); 
    //["a", "b", "c"]์ฒ˜๋Ÿผ ํ…์ŠคํŠธ ํƒ€์ž…์œผ๋กœ ์ €์žฅ๋จ
}
</script>

5๏ธโƒฃ ํŽ˜์ด์ง€ ๋กœ๋“œ ์‹œ, ๊ธฐ์กด ํ•  ์ผ ๋ชฉ๋ก ๊ฐ€์ ธ์˜ค๊ธฐ

๐Ÿฉต ํŽ˜์ด์ง€๊ฐ€ ๋กœ๋“œ๋  ๋•Œ, localStorage.getItem(todos)์„ ์‚ฌ์šฉํ•˜์—ฌ ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ , JSON.parse()๋กœ ๋‹ค์‹œ ๊ฐ์ฒด ๋ฐฐ์—ด๋กœ ๋ณ€ํ™˜
๐Ÿ”น JSON.stringify() : ๋ฐฐ์—ด/๊ฐ์ฒด๋ฐ์ดํ„ฐ๋ฅผ "ํ…์ŠคํŠธ"ํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜
๐Ÿ”น JSON.parse() : ํ…์ŠคํŠธ๋ฅผ "๋ฐฐ์—ด"๋กœ ๋ณ€ํ™˜

๐Ÿฉต localStorage์— ์ €์žฅ๋œ ๊ฐ’์ด ์กด์žฌํ•œ๋‹ค๋ฉด
๐Ÿ”น ๋ณ€ํ™˜๋œ ๋ฐ์ดํ„ฐ๋ฅผ todos ๋ฐฐ์—ด์— ํ• ๋‹นํ•˜๊ณ , paintTodo()๋กœ ๋ชฉ๋ก์„ ๋‹ค์‹œ ๊ทธ๋ฆฝ๋‹ˆ๋‹ค.
๐Ÿ”น forEach()**๋Š” ๋ฐฐ์—ด์˜ ๋ชจ๋“  ํ•ญ๋ชฉ์— ๋Œ€ํ•ด ๋ฐ˜๋ณต ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ๋•Œ ์‚ฌ์šฉ. localStorage์—์„œ ๊ฐ€์ ธ์˜จ ํ•  ์ผ ๋ชฉ๋ก์„ ํ™”๋ฉด์— ํ‘œ์‹œํ•  ๋•Œ ์‚ฌ์šฉ

<script>
const savedTodos = localStorage.getItem(TODOS_KEY);
// console.log(savedTodos);

if(savedTodos !== null){
    const parsedTodos = JSON.parse(savedTodos); 
    // console.log(parsedTodos);
    todos = parsedTodos;
    parsedTodos.forEach(paintTodo);
}
</script>
profile
ํผ๋ธ”๋ฆฌ์…” / ์ž‘์—… ๊ธฐ๋กœ๋„v

0๊ฐœ์˜ ๋Œ“๊ธ€