기본 세팅
<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 handleToDoSubmit(event) {
event.preventDefault();
// input의 현재 value를 새로운 변수에 복사하는 것.
const newTodo = toDoInput.value;
toDoInput.value = "";
}
toDoForm.addEventListener("submit", handleToDoSubmit);
ToDo 추가하기
const toDoForm = document.getElementById("todo-form");
const toDoInput = document.querySelector(" #todo-form input");
const toDoList = document.getElementById("todo-list");
// handleToDoSubmit에서 호출한 submit이벤트의 결과를 보여주는 함수.
function paintToDo(newTodo) {
const li = document.createElement("li");
const span = document.createElement("span");
// span을 li의 자식으로 넣고 싶은 코드 / span을 li내부에 집어넣다.
li.appendChild(span);
// span의 텍스트는 handleToDoSubmit에서 온 newTodo 텍스트가 되는 것이다. / 텍스트를 span내부에 넣다.
span.innerText = newTodo;
// 새로운 li를 toDoList에 추가한다.
toDoList.appendChild(li);
}
function handleToDoSubmit(event) {
event.preventDefault();
// newTodo === input의 value를 비우기 전의 값을 나타내는 string이다.
const newTodo = toDoInput.value;
toDoInput.value = "";
// 그 다음 입력값을 paintToDo에 넣어서 호출하는 것.
paintToDo(newTodo);
}
toDoForm.addEventListener("submit", handleToDoSubmit);
ToDo 삭제하기 (todo삭제하는 버튼만들기)
❌ button 클릭했을 때 li 사라지기
function deleteToDo(event) {
console.log(event);
}
// handleToDoSubmit에서 호출한 submit이벤트의 결과를 보여주는 함수.
function paintToDo(newTodo) {
const li = document.createElement("li");
const span = document.createElement("span");
// span의 텍스트는 handleToDoSubmit에서 온 newTodo 텍스트가 되는 것이다. / 텍스트를 span내부에 넣다.
span.innerText = newTodo;
// Text추가할 때 삭제하는 button 만들기
const button = document.createElement("button");
// button텍스트를 X이모지로 대체하기
button.innerText = "❌";
// button클릭할 때 eventlistener주기
button.addEventListener("click", deleteToDo);
// span, button을 li의 자식으로 넣고 싶은 코드
li.appendChild(span);
li.appendChild(button);
// 새로운 li를 toDoList에 추가한다.
toDoList.appendChild(li);
}
텍스트를 추가하다보면 클릭이 다 똑같다는 문제점이 발생한다.
자세히 알아보고 싶으면.
console.log(event) 하고 button클릭했을 때 나오는 event들 중에 target: button 이라는 것이 보일 것이다.
console.log(event.target) 해보면 어떤 button이 클릭되었는지를 알려준다.
console.dir(event.target)해보면 button안을 들여다볼 수 있는데, parentNode / parentElement 보일 것이다..
parentNode / parentElement는 그 button의 부모를 알 수 있다. parentNode: li 우리가 찾던 li이다.
function deleteToDo(event) {
// target은 클릭된 HTML element이다.
// parentElemnent 는 클릭된 element의 부모이다.
console.log(event.target.parentElement);
}
//X라는 이모지 클릭했을 때 li 사라지기
function deleteToDo(event) {
// target은 클릭된 HTML element이다. target === button
// parentElemnent 는 클릭된 element의 부모이다.
// 우리가 삭제하고 싶은 li이다.
const li = event.target.parentElement;
li.remove();
}
// handleToDoSubmit에서 호출한 submit이벤트의 결과를 보여주는 함수.
function paintToDo(newTodo) {
const li = document.createElement("li");
const span = document.createElement("span");
// span의 텍스트는 handleToDoSubmit에서 온 newTodo 텍스트가 되는 것이다. / 텍스트를 span내부에 넣다.
span.innerText = newTodo;
// Text추가할 때 삭제하는 button 만들기
const button = document.createElement("button");
// button텍스트를 X이모지로 대체하기
button.innerText = "❌";
// button클릭할 때 eventlistener주기
button.addEventListener("click", deleteToDo);
// span, button을 li의 자식으로 넣고 싶은 코드
li.appendChild(span);
li.appendChild(button);
// 새로운 li를 toDoList에 추가한다.
toDoList.appendChild(li);
}
ToDo 저장하기
// newTodo가 행해질 때마다 그 텍스를 toDos array에 push하고 싶어진다.
const toDos = [];
//toDos array의 내용을 localStorage에 넣는 함수.
function saveToDos() {
localStorage.setItem("todos", toDos);
}
//X라는 이모지 클릭했을 때 li 사라지기
function deleteToDo(event) {
// target은 클릭된 HTML element이다. target === button
// parentElemnent 는 클릭된 element의 부모이다.
// 우리가 삭제하고 싶은 li이다.
const li = event.target.parentElement;
li.remove();
}
// handleToDoSubmit에서 호출한 submit이벤트의 결과를 보여주는 함수.
function paintToDo(newTodo) {
const li = document.createElement("li");
const span = document.createElement("span");
// span의 텍스트는 handleToDoSubmit에서 온 newTodo 텍스트가 되는 것이다. / 텍스트를 span내부에 넣다.
span.innerText = newTodo;
// Text추가할 때 삭제하는 button 만들기
const button = document.createElement("button");
// button텍스트를 X이모지로 대체하기
button.innerText = "❌";
// button클릭할 때 eventlistener주기
button.addEventListener("click", deleteToDo);
// span, button을 li의 자식으로 넣고 싶은 코드
li.appendChild(span);
li.appendChild(button);
// 새로운 li를 toDoList에 추가한다.
toDoList.appendChild(li);
}
function handleToDoSubmit(event) {
event.preventDefault();
// newTodo === input의 value를 비우기 전의 값을 나타내는 string이다.
const newTodo = toDoInput.value;
// input을 비우고,
toDoInput.value = "";
// toDos array를 가지고 와서 newTodo를 toDos array에 push하는 것.
toDos.push(newTodo);
// 화면에 toDo를 나타내주고,
paintToDo(newTodo);
// toDo들을 저장하기
saveToDos();
}
// 사용자가 form을 submit하면,
toDoForm.addEventListener("submit", handleToDoSubmit);
단순 텍스트로 저장되는 걸 원치 않기 때문에,
브라우저의 기능 중에 JavaScript object 나 array 나 어떤 것이든 String으로 바꿔주는 기능이 있어야 한다.
▶JSON.stringify()

// newTodo가 행해질 때마다 그 텍스를 toDos array에 push하고 싶어진다.
const toDos = [];
//toDos array의 내용을 localStorage에 넣는 함수.
function saveToDos() {
localStorage.setItem("todos", JSON.stringify(toDos));
}
ToDo 로딩하기


localStorage.getItem("todos")는 단순한 string //
JSON.parse(localStorage.getItem("todos"))는 실제로 살아있는 배열(array)를 얻게 되는 것.
localStorage에서 온 string이 JavaScript에서 사용 가능한 object로 변하게 하는 기능 ▶ JSON.parse()
// toDos Loading하기
const savedToDos = localStorage.getItem(TODOS_KEY);
console.log(savedToDos);
if (savedToDos) {
// localStorage에서 온 string이 살아있는 JavaScript object로 변하게 하는 것.
const parsedToDos = JSON.parse(savedToDos);
console.log(parsedToDos);
}

콘솔창 결과를 보면, array에 있는 각각의 item에 대해 function을 실행하고 싶을 것이다.
▶ forEach() : 화살표 함수
★ ex. parsedToDos.forEach(paintTodo) - 이 paintToDo를 parsedToDos 배열의 요소마다 실행한다. ★
function sayHello(item) {
console.log("This is the turn of", item);
}
// toDos Loading하기
const savedToDos = localStorage.getItem(TODOS_KEY);
if (savedToDos) {
// localStorage에서 온 string이 살아있는 JavaScript object로 변하게 하는 것.
const parsedToDos = JSON.parse(savedToDos);
console.log(parsedToDos);
// forEach는 array의 각 item에 대해 function을 실행하게 해주는 역할.
parsedToDos.forEach(sayHello);
}

//방법 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));
// toDos Loading하기
const savedToDos = localStorage.getItem(TODOS_KEY);
if (savedToDos) {
// localStorage에서 온 string이 살아있는 JavaScript object로 변하게 하는 것.
const parsedToDos = JSON.parse(savedToDos);
// forEach는 array의 각 item에 대해 function을 실행하게 해주는 역할.
// 각각 item을 화면에 그려주고 싶다.
parsedToDos.forEach(paintToDo);
}
이 상태에서 새로고침하고 item을 추가하고 localStorage창을 보면 이전의 저장되어있던 array들은 사라지고 추가한 array만 보일 것이다. 왜냐하면, 원래 const toDos = []; 빈값으로 해놨기 때문에......
▶ 이전의 저장되어있던 array들과 추가되는 array들도 함께 나타내는 방법!!!
// toDos 는 항상 빈 array로 시작한다.
// 이전 newTodo 와 계속 추가되는 newTodo를 유지하고 싶기 때문에 const => let
let toDos = [];
// toDos Loading하기
const savedToDos = localStorage.getItem(TODOS_KEY);
if (savedToDos) {
// localStorage에서 온 string이 살아있는 JavaScript object로 변하게 하는 것.
const parsedToDos = JSON.parse(savedToDos);
// toDos에 parsedToDos를 넣어서 전에 있던 toDo들을 복원할 것임. 이전의 toDos 사라지기 않기 위해.
toDos = parsedToDos;
// forEach는 array의 각 item에 대해 function을 실행하게 해주는 역할.
// item을 화면에 그려주고 싶다.
parsedToDos.forEach(paintToDo);
}
이렇게 되면, 또 삭제하는 button을 클릭했지만, 새로고침해도 다시 원래 저장되던 상태로 되돌아간다.라는 문제점!
ToDo 삭제하기
toDos array (데이터베이스) ≠ local Storage (toDos array를 복사해두는 곳.)
Step 1. application에 있는 데이터베이스를 지운다.
Step 2. 랜덤으로 ID를 만드는 방법. 마치 Date.now()처럼....
▶ 데이터베이스에게 id를 저장하는 옵션
// handleToDoSubmit에서 호출한 submit이벤트의 결과를 보여주는 함수.
// paintToDo는 text를 받았던 함수였다.
// 이제는 object로 받아야 하는 상태.
function paintToDo(newTodo) {
const li = document.createElement("li");
// id로 각각의 item을 구별하고 싶다.
li.id = newTodo.id;
const span = document.createElement("span");
// span의 텍스트는 handleToDoSubmit에서 온 newTodo 텍스트가 되는 것이다. / 텍스트를 span내부에 넣다.
// text로 받았던 걸 object로 받아야 하기 때문에 newTodo.text로 고친다.
span.innerText = newTodo.text;
// Text추가할 때 삭제하는 button 만들기
const button = document.createElement("button");
// button텍스트를 X이모지로 대체하기
button.innerText = "❌";
// button클릭할 때 eventlistener주기
button.addEventListener("click", deleteToDo);
// span, button을 li의 자식으로 넣고 싶은 코드
li.appendChild(span);
li.appendChild(button);
// 새로운 li를 toDoList에 추가한다.
toDoList.appendChild(li);
}
function handleToDoSubmit(event) {
event.preventDefault();
// newTodo === input의 value를 비우기 전의 값을 나타내는 string이다.
const newTodo = toDoInput.value;
// input을 비우고,
toDoInput.value = "";
// text 대신 object를 push한다.
const newTodoObj = {
text: newTodo,
id: Date.now(),
};
// toDos array를 가지고 와서 newTodo를 toDos array에 push하는 것.
// 데이터베이스로 매번 사용자가 적어둔 text를 push한다.
// toDos 배열에 newTodoObj추가하게 된다.
toDos.push(newTodoObj);
// 화면에 toDo를 나타내주고,
// paintToDo에는 text 대신 object로 변하고 싶어 newTodoObj추가하게 된다.
paintToDo(newTodoObj);
// toDo들을 저장하기
saveToDos();
}
Step 3.
▶ array에서 item을 지우는 법
▶ 지우고 싶은 item을 제외하고 새 array를 만드는 일 ▶ filter() - 선택옵션 / forEach()와 비슷하다.
★ 새 array에 item을 유지하고 싶으면 true를 리턴해야 한다.









//X라는 이모지 클릭했을 때 li 사라지기
function deleteToDo(event) {
// target은 클릭된 HTML element이다. target === button
// parentElemnent 는 클릭된 element의 부모이다.
// 우리가 삭제하고 싶은 li이다.
const li = event.target.parentElement;
li.remove();
// 클릭했던 li의 id를 갖고 있는 toDo를 지우고 싶다.
// toDo의 id가 li의 id와 다른 걸로 남기고 싶다.
toDos = toDos.filter((toDo) => toDo.id !== li.id);
}
이 상태에서 localStorage 빈 곳을 삭제하고 다시 입력하면, 삭제하는 button클릭해도 콘솔창에는 button클릭 안한 것과 같은 결과가 나온다. 왜냐하면, id는 number이기 때문에.....
즉, li.id는 string타입이다. toDo.id는 number타입이다.
//toDos array의 내용을 localStorage에 넣는 함수.
// JSON.stringify === toDos를 string으로 바꾸는 형태.
function saveToDos() {
localStorage.setItem(TODOS_KEY, JSON.stringify(toDos));
}
//X라는 이모지 클릭했을 때 li 사라지기
function deleteToDo(event) {
// target은 클릭된 HTML element이다. target === button
// parentElemnent 는 클릭된 element의 부모이다.
// 우리가 삭제하고 싶은 li이다.
const li = event.target.parentElement;
li.remove();
// 클릭했던 li의 id를 갖고 있는 toDo를 지우고 싶다.
// toDo의 id가 li의 id와 다른 걸로 남기고 싶다.
// li.id == string타입 / toDo.id == number타입
// 그래서 parseInt 이용해서 문자열로 바꿔준다.
// toDos DB에서 todo를 지운 뒤에
toDos = toDos.filter((toDo) => toDo.id !== parseInt(li.id));
// saveToDos를 한 번 더 부른다.
saveToDos();
}
최종적 코드
const toDoForm = document.getElementById("todo-form");
const toDoInput = document.querySelector(" #todo-form input");
const toDoList = document.getElementById("todo-list");
const TODOS_KEY = "todos";
// newTodo가 행해질 때마다 그 텍스를 toDos array에 push하고 싶어진다.
// toDos 는 항상 빈 array로 시작한다.
// 이전 newTodo 와 계속 추가되는 newTodo를 유지하고 싶기 때문에 const => let
// 데이터베이스에 ToDo내용을 추가하는 곳.
let toDos = [];
//toDos array의 내용을 localStorage에 넣는 함수.
// JSON.stringify === toDos를 string으로 바꾸는 형태.
function saveToDos() {
localStorage.setItem(TODOS_KEY, JSON.stringify(toDos));
}
//X라는 이모지 클릭했을 때 li 사라지기
function deleteToDo(event) {
// target은 클릭된 HTML element이다. target === button
// parentElemnent 는 클릭된 element의 부모이다.
// 우리가 삭제하고 싶은 li이다.
const li = event.target.parentElement;
li.remove();
// 클릭했던 li의 id를 갖고 있는 toDo를 지우고 싶다.
// toDo의 id가 li의 id와 다른 걸로 남기고 싶다.
// li.id == string타입 / toDo.id == number타입
// 그래서 parseInt 이용해서 문자열로 바꿔준다.
// toDos DB에서 todo를 지운 뒤에
toDos = toDos.filter((toDo) => toDo.id !== parseInt(li.id));
// saveToDos를 한 번 더 부른다.
saveToDos();
}
// handleToDoSubmit에서 호출한 submit이벤트의 결과를 보여주는 함수.
// paintToDo는 text를 받았던 함수였다.
// 이제는 object로 받아야 하는 상태.
function paintToDo(newTodo) {
const li = document.createElement("li");
// id로 각각의 item을 구별하고 싶다.
li.id = newTodo.id;
const span = document.createElement("span");
// span의 텍스트는 handleToDoSubmit에서 온 newTodo 텍스트가 되는 것이다. / 텍스트를 span내부에 넣다.
// text로 받았던 걸 object로 받아야 하기 때문에 newTodo.text로 고친다.
span.innerText = newTodo.text;
// Text추가할 때 삭제하는 button 만들기
const button = document.createElement("button");
// button텍스트를 X이모지로 대체하기
button.innerText = "❌";
// button클릭할 때 eventlistener주기
button.addEventListener("click", deleteToDo);
// span, button을 li의 자식으로 넣고 싶은 코드
li.appendChild(span);
li.appendChild(button);
// 새로운 li를 toDoList에 추가한다.
toDoList.appendChild(li);
}
function handleToDoSubmit(event) {
event.preventDefault();
// newTodo === input의 value를 비우기 전의 값을 나타내는 string이다.
const newTodo = toDoInput.value;
// input을 비우고,
toDoInput.value = "";
// text 대신 object를 push한다.
const newTodoObj = {
text: newTodo,
id: Date.now(),
};
// toDos array를 가지고 와서 newTodo를 toDos array에 push하는 것.
// 데이터베이스로 매번 사용자가 적어둔 text를 push한다.
// toDos 배열에 newTodoObj추가하게 된다.
toDos.push(newTodoObj);
// 화면에 toDo를 나타내주고,
// paintToDo에는 text 대신 object로 변하고 싶어 newTodoObj추가하게 된다.
paintToDo(newTodoObj);
// toDo들을 저장하기
saveToDos();
}
// 사용자가 form을 submit하면,
toDoForm.addEventListener("submit", handleToDoSubmit);
// toDos Loading하기
const savedToDos = localStorage.getItem(TODOS_KEY);
if (savedToDos !== null) {
// localStorage에서 온 string이 살아있는 JavaScript object로 변하게 하는 것.
// JSON.parse === toDos 살아있는 array가 된 형태.
const parsedToDos = JSON.parse(savedToDos);
// toDos에 parsedToDos를 넣어서 전에 있던 toDo들을 복원할 것임. 이전의 toDos 사라지기 않기 위해.
toDos = parsedToDos;
// forEach는 array의 각 item에 대해 function을 실행하게 해주는 역할.
// item을 화면에 그려주고 싶다.
// forEach함수는 이 paintToDo를 parsedToDos 배열의 요소마다 실행한다.
parsedToDos.forEach(paintToDo);
}
'개발언어 > JavaScript' 카테고리의 다른 글
[JavaScript] 데이터 타입 Data Types 의 종류 (0) | 2022.07.27 |
---|---|
Weather날씨 만들기 (0) | 2021.09.04 |
Quotes and Background 명언 만들기 (0) | 2021.09.02 |
Clock만들기 (0) | 2021.09.01 |
Login만들기 (0) | 2021.09.01 |