
7강. todo리스트
먼저 7.0에서 새 파일을 만들어주고 시작한다.
7.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">
<link rel="stylesheet" href="style.css">
<title>Momentum</title>
</head>
<body>
<form class="hidden" id="login-form">
<input
required
maxlength="15"
type="text"
placeholder="What is your name"/>
<button>Log In</button>
</form>
<h1 id="greeting" class="hidden"></h1>
<form id="todo-form">
<input type="text" placeholder="Write a To Do and Press Enter" required/>
</form>
<ul id="todo-list"></ul>
<div id="quote">
<span></span>
<span></span>
</div>
<h2 id="clock">00:00</h2>
<script src="greetings.js"></script>
<script src="clock.js"></script>
<script src="quotes.js"></script>
<script src="background.js"></script>
<script src="todo.js"></script>
</body>
</html>
아래는 새로 만든 todo.js 속 js코드이다.
const toDoForm = document.getElementById("todo-form");
const toDoInput = toDoForm.querySelector("#todo-form input");
const toDoLlist= document.getElementById("todo-list");
function handleToDoSubmit(event)
{
event.preventDefault();
const newTodo = toDoInput.value;
toDoInput.value="";
}
toDoForm.addEventListener("submit",handleToDoSubmit);
7.1: 리스트 속 내용 만들기
const toDoForm = document.getElementById("todo-form");
const toDoInput = toDoForm.querySelector("#todo-form input");
const toDoLlist= document.getElementById("todo-list");
function paintToDo(newTodo)
{
const li = document.createElement("li");
const span = document.createElement("span");
li.appendChild(span);
span.innerText = newTodo;
toDoLlist.appendChild(li);
}
function handleToDoSubmit(event)
{
event.preventDefault();
const newTodo = toDoInput.value;
toDoInput.value="";
paintToDo(newTodo);
}
toDoForm.addEventListener("submit",handleToDoSubmit);
여기서는 투두리스트 속에 들어갈 내용들을 표시해준다. 새로움 함수 안에 li를 만들고, 그 속에 span을 만들어주어 span안에 넣고 싶은 내용을 넣는다. 하지만 이렇게 하는 경우, todolist는 정상적으로 작동하지만 새로고침했을 때 없어지는 것과 삭제하는 것이 문제이다.
7.2 to do 삭제하기
저번 강의에서 삭제하는 게 안되는 것이 문제라고 했었는데, 이것을 해결하기 위해서 삭제버튼을 만들어줘야 한다. 먼저 삭제버튼을 만들면서 어떤 내용에 맞는 버튼을 누른것인지 알아야한다. 이것을 실행하기 위해서는 새로운 함수를 만들어내야 하는데, 거기서 사용하는 함수가 deleteToDo함수이다.
function deleteToDo(event)
{
console.dir(event.target.parentElement.innerText);
}
const button을 통해서 삭제버튼을 추가해주고, 이 버튼을 누른 "event"를 나타내주기 위해서 전에 배웠던 addEventListener을 사용해준다. 삭제버튼을 눌렀을 때 그 부분에 해당하는 내용을 삭제하기 위해서 remove를 쓴다. 최종 코드는 아래와 같다.
const toDoForm = document.getElementById("todo-form");
const toDoInput = toDoForm.querySelector("#todo-form input");
const toDoLlist= document.getElementById("todo-list");
const toDos = [];
function deleteToDo(event)
{
const li = event.target.parentElement;
li.remove();
}
function paintToDo(newTodo)
{
const li = document.createElement("li");
const span = document.createElement("span");
span.innerText = newTodo;
const button = document.createElement("button");
button.innerText="✖️";
button.addEventListener("click",deleteToDo);
li.appendChild(span);
li.appendChild(button);
toDoLlist.appendChild(li);
}
function handleToDoSubmit(event)
{
event.preventDefault();
const newTodo = toDoInput.value;
toDoInput.value="";
paintToDo(newTodo);
}
toDoForm.addEventListener("submit",handleToDoSubmit);
7.3 저장하기
내가 만든 todo를 저장하기 위해서는 local storage에 저장해야 한다.
function saveToDos()
{
localStorage.setItem("todos",JSON.stringify(toDos));
}
새로운 todo를 기억하기 위해서 새로 만들어진 newToDo를 toDo 배열에 push 해주어야 한다. 새로 만들어진 내용을 배열안에 넣어주고 나면 그것을 기억하기 위해서 새로운 함수 saveToDos를 사용한다.
const toDoForm = document.getElementById("todo-form");
const toDoInput = toDoForm.querySelector("#todo-form input");
const toDoLlist= document.getElementById("todo-list");
const toDos = [];
function saveToDos()
{
localStorage.setItem("todos",JSON.stringify(toDos));
}
function deleteToDo(event)
{
const li = event.target.parentElement;
li.remove();
}
function paintToDo(newTodo)
{
const li = document.createElement("li");
const span = document.createElement("span");
span.innerText = newTodo;
const button = document.createElement("button");
button.innerText="✖️";
button.addEventListener("click",deleteToDo);
li.appendChild(span);
li.appendChild(button);
toDoLlist.appendChild(li);
}
function handleToDoSubmit(event)
{
event.preventDefault();
const newTodo = toDoInput.value;
toDoInput.value="";
toDos.push(newTodo);
paintToDo(newTodo);
saveToDos();
}
toDoForm.addEventListener("submit",handleToDoSubmit);
7.4 로딩1
전 강의에서 쓴 코드는 새로고침이 되어도 우리가 local storage에 저장해두었기 때문에 todo를 모두 기억하고 있다. 하지만 화면에 직접 나타나지 않는다는 점이 문제점이다.
문자열인 todo를 넣은 localstorage를 parse해서 배열로 바꿔주어야 한다. 이때 JSON.parse(localStorage.getItem("todos")) 이렇게 쓰면 todos를 배열의 자료형으로 바꿀 수 있다.
forEach라는 함수를 실행시키면 배열 속의 각각의 원소에 실행시켜준다.
const toDoForm = document.getElementById("todo-form");
const toDoInput = toDoForm.querySelector("#todo-form input");
const toDoLlist= document.getElementById("todo-list");
const TODOS_KEY = "todos";
let toDos = [];
function saveToDos()
{
localStorage.setItem("todos",JSON.stringify(toDos));
}
function deleteToDo(event)
{
const li = event.target.parentElement;
li.remove();
}
function paintToDo(newTodo)
{
const li = document.createElement("li");
const span = document.createElement("span");
span.innerText = newTodo;
const button = document.createElement("button");
button.innerText="✖️";
button.addEventListener("click",deleteToDo);
li.appendChild(span);
li.appendChild(button);
toDoLlist.appendChild(li);
}
function handleToDoSubmit(event)
{
event.preventDefault();
const newTodo = toDoInput.value;
toDoInput.value="";
toDos.push(newTodo);
paintToDo(newTodo);
saveToDos();
}
toDoForm.addEventListener("submit",handleToDoSubmit);
const savedToDos = localStorage.getItem(TODOS_KEY);
if(savedToDos !== null){
const parsedToDos = JSON.parse(savedToDos);
console.log(parsedToDos);
parsedToDos.forEach(item) => console.log("this is the turn of", item)
}
최종코드이다. 여기서 마지막에 =>를 썼는데 이것은 arrow 함수인데,
parsedToDos.forEach(item) => console.log("this is the turn of", item)
와
function sayHello(item){
console.log("this is the turn of", item);
}
가 같은 뜻이라서 둘 중에 어떤 방법을 써도 상관없다.
7.5 로딩2
이제 todo배열 속에 있는 각각의 item들에 대해서 그 item들을 나타낼 것인데, 이미 paintToDo 함수가 있기 때문에 그 함수를 호출해주기만 하면 된다.
하지만 여기서 문제는 처음에 todo배열에 abc를 쓰고 그 다음에 def를 추가해주었을 때, 새로고침하면 localstorage에 abcdef가 저장되는 것이 아니라 def만 저장되어 나타난다는 점이다. 이를 해결하기 위해서 forEach를 수정해주어야 한다.
if(savedToDos !== null){
const parsedToDos = JSON.parse(savedToDos);
toDos = parsedToDos;
parsedToDos.forEach(paintToDo);
}
이렇게 하면 예전의 것도 다 보관할 수 있게 된다.
7.6 삭제1
하지만 여기서 또 문제는 내가 화면에서 todo들을 삭제를 해도 새로고침하면 삭제된 것이 반영되지 않고 다시 생겨난다. 화면에서는 삭제를 했어도 localstorage에서는 아직 기억하고 있고, 삭제하지 않았기 때문이다.
먼저 어떤 item을 지워야할지를 알아야 한다. 위에서 한 방법대로 todotext로 구분을 한다면 같은 문자가 있을 때 어느 것을 지운 것인지 구분할 수가 없기 때문에 다른 방법을 생각해봐야 한다.
text를 push하는 게 아니라 object를 push하면 된다.
function handleToDoSubmit(event)
{
event.preventDefault();
const newTodo = toDoInput.value;
toDoInput.value="";
const newToDoObj = {
text:newTodo,
id: Date.now();
}
toDos.push(newTodoObj);
paintToDo(newTodo);
saveToDos();
}
7.7 삭제2
forEach함수는 paintToDo를 parsedToDos 배열의 요소마다 각각 실행한다. 만약 우리가 무엇을 지우고 싶을 때 우리가 실제로 배열에서 그것을 삭제하는 것이 아니라 지우고 싶은 요소를 제외한 새로운 배열을 만들어내는 것이다. 이 제외하고 싶은 대상을 제외한 새로운 배열을 만들어내는 과정에서 사용하는 것이 바로 filter함수이다.
function sexyFilter()
{
}
[1,2,3,4].filter(sexyFilter)
여기에서 sexyfilter함수는 무조건 true를 리턴해야한다. 만약 false가 리턴되면 그 요소는 이 배열 안에 속하지 않을 것이다.
7.8 삭제3
filter함수가 새로운 배열을 준다는 것을 저번에서 배웠는데, 여기에 조건을 부여해서 새로운 함수를 만들어낼 수 있다. 예를 들어 1,2,3,4 에서 item > 2인 경우에서 새로운 배열을 만들도록 하면 3,4가 출력된다.
근데 계속 해도 첫화면이

이렇게 뜨고 새로고침해도 계속 똑같이 뜨는데 뭐가 잘못된지 모르게씀,,,,
코드 계속 봐도 머가 잘못댄지 모르겠슴다
const toDoForm = document.getElementById("todo-form");
const toDoInput = toDoForm.querySelector("#todo-form input");
const toDoLlist= document.getElementById("todo-list");
const TODOS_KEY = "todos";
let toDos = [];
function saveToDos(){
localStorage.setItem("todos",JSON.stringify(toDos));
}
function deleteToDo(event){
const li = event.target.parentElement;
li.remove();
toDos = toDos.filter((toDo) => toDo.id !== li.id);
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);
toDoLlist.appendChild(li);
}
function handleToDoSubmit(event){
event.preventDefault();
const newTodo = toDoInput.value;
toDoInput.value="";
const newTodoObj = {
text:newTodo,
id: Date.now(),
};
toDos.push(newTodoObj);
paintToDo(newTodo);
saveToDos();
}
toDoForm.addEventListener("submit",handleToDoSubmit);
const savedToDos = localStorage.getItem(TODOS_KEY);
if(savedToDos !== null){
const parsedToDos = JSON.parse(savedToDos);
toDos = parsedToDos;
parsedToDos.forEach(paintToDo);
}
포깅에여,,,살려주세요
.
.
.
.
.
밤새 해봤는데 드디어 해냈슴미다...
const toDoForm = document.getElementById("todo-form");
const toDoInput = document.querySelector("#todo-form input");
const toDoLlist= 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 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);
toDoLlist.appendChild(li);
}
function handleToDoSubmit(event){
event.preventDefault();
const newTodo = toDoInput.value;
toDoInput.value="";
const newTodoObj = {
text:newTodo,
id: Date.now(),
};
toDos.push(newTodoObj);
paintToDo(newTodoObj);
saveToDos();
}
toDoForm.addEventListener("submit",handleToDoSubmit);
const savedToDos = localStorage.getItem(TODOS_KEY);
if(savedToDos !== null){
const parsedToDos = JSON.parse(savedToDos);
toDos = parsedToDos;
parsedToDos.forEach(paintToDo);
}
자잘자잘한 오류들이 많았어서 하나하나 왜 안되는지 설명하기는 복잡,,