# Todo List

Doozuu·2022년 11월 1일
0

Javascript

목록 보기
6/99

1. Setup

handleToDoSubmit 함수 만들기

const toDoForm = document.getElementById("todo-form");
const toDoInput = document.querySelector("#todo-form input");
const toDoList = document.getElementById("todo-list");

function handleToDoSubmit(event) {
event.preventDefault(); // 엔터 누르면 자동으로 새로고침 되는 기능 제거
const newTodo = toDoInput.value; // 입력값 변수에 저장
toDoInput.value = ""; // 엔터 누르면 입력값이 입력창에 안 보이게
}

toDoForm.addEventListener("submit", handleToDoSubmit);


2. Adding Todo

paintToDo 함수 만들기

  1. 입력한 value를 변수에 저장
  2. js로 li를 만들어서 innerText로 입력값 넣기
  3. list에 append
const toDoForm = document.getElementById("todo-form");
const toDoInput = document.querySelector("#todo-form input");
const toDoList = document.getElementById("todo-list");

function paintToDo(newTodo) {
const todoLi = document.createElement("li"); // html에 li 만들기
const todoSpan = document.createElement("span"); // html에 span 만들기
todoLi.appendChild(todoSpan); // li 안에 span 넣기(li > span)
span.innerText = newTodo; // span에 입력값 넣기
toDoList.appendChild(todoLi); // list에 li 넣어서 입력값 보여주기
}

function handleToDoSubmit(event) {
event.preventDefault(); 
const newTodo = toDoInput.value; 
toDoInput.value = ""; 
paintToDo(newTodo); // 입력값 저장한 변수 보내기
}

toDoForm.addEventListener("submit", handleToDoSubmit);


3. Deleting Todo

deleteToDo 함수 만들기

  1. Js로 html에 버튼 만들기(삭제 버튼)
  2. addEventListener로 버튼 클릭 이벤트 캐치하기
  3. 어떤 버튼 눌렀는지 구분하기 (어떤 li를 제거해야 하는지 알기 위해)
  4. 삭제하기

⭐️ 어떤 버튼 클릭했는지 구분하기

event.target.parentElement

event.target : 클릭한 <button>
event.target.parentElement : 클릭한 버튼의 부모요소인 <li>
event.target.parentElement.innerText : li의 innerText : 일정1:~~

⭐️ 요소 삭제하기

remove( )


const toDoForm = document.getElementById("todo-form");
const toDoInput = document.querySelector("#todo-form input");
const toDoList = document.getElementById("todo-list");

function deleteToDo(event){
const delLi = event.target.parentElement; // 클릭한 버튼의 li(일정+버튼 부분)
delLi.remove(); // 해당 요소 제거하기
}

function paintToDo(newTodo) {
const todoLi = document.createElement("li"); 
const todoSpan = document.createElement("span"); 
span.innerText = newTodo; 
const button = document.createElement("button"); // 삭제 버튼 만들기
button.innerText = "❌";
button.addEventListener("click", deleteToDo); // 삭제 버튼 클릭하면 함수 실행
todoLi.appendChild(todoSpan); 
todoLi.appendChild(button); // li 안에 button 넣기(li > button)
toDoList.appendChild(todoLi); 
}

function handleToDoSubmit(event) {
event.preventDefault(); 
const newTodo = toDoInput.value; 
toDoInput.value = ""; 
paintToDo(newTodo);
}

toDoForm.addEventListener("submit", handleToDoSubmit);


4. Saving Todo

⭐️ 브라우저에 저장하기

localStorage.setItem( )

새로고침하면 todo가 저장되지 않고 사라지는 문제 해결하기 위해 사용.

  1. 입력받은 todo를 빈 배열에 저장하기.
  2. 배열을 localStorage에 넣기.
    But, localStorage에는 오직 텍스트만 저장할 수 있음. (배열 저장 x)
    ex) ["a","b","c"] -> a,b,c
    ⛔️ 그러나 텍스트로 저장시 새로고침하고 일정을 추가하면 기존 데이터가 사라지는 문제 발생
    이유: const toDos = [] -> 배열이 항상 비어있기 때문에 기존 데이터가 저장되지 않음.
  • 해결방법:
  1. 업데이트 할 수 있도록 const를 let으로 바꿔줌.
    let toDos = [];
  2. 빈 배열에 기존 데이터 넣어줌.
    toDos = parsedToDos;

⭐️ JSON.stringify( )

: array를 다 string으로 바꿔줌.
단순 텍스트로 저장되지 않고 "배열 형태"인 텍스트로 저장되도록.
ex) ["a","b","c"] -> "[\"a\",\"b\",\"c\"]"

⭐️ JSON.parse( )

: string을 array로 바꿔줌.
단순한 string을 "살아있는" Javascript object로 만들기
ex) "[\"a\",\"b\",\"c\"]" -> ["a","b","c"]


const toDoForm = document.getElementById("todo-form");
const toDoInput = document.querySelector("#todo-form input");
const toDoList = document.getElementById("todo-list");
let toDos = []; // 입력값 저장할 배열
const TODOS_KEY = "todos"

function saveToDos(){
localStorage.setItem(TODOS_KEY, JSON.stringify(toDos)); // localStorage에 입력값 담은 배열 저장.(string)
}

function deleteToDo(event){
const delLi = event.target.parentElement; 
delLi.remove();
}

function paintToDo(newTodo) {
const todoLi = document.createElement("li"); 
const todoSpan = document.createElement("span"); 
span.innerText = newTodo;
const button = document.createElement("button"); 
button.innerText = "❌";
button.addEventListener("click", deleteToDo); 
todoLi.appendChild(todoSpan); 
todoLi.appendChild(button); 
toDoList.appendChild(todoLi);
}

function handleToDoSubmit(event) {
event.preventDefault(); 
const newTodo = toDoInput.value; 
toDoInput.value = ""; 
toDos.push(newTodo); 
paintToDo(newTodo); 
saveToDos(); // localStorage에 입력값 저장하기
}

toDoForm.addEventListener("submit", handleToDoSubmit);

const savedToDos = localStorage.getItem(TODOS_KEY); // 입력값이 없을 때에는 null 출력됨.

if(savedToDos !== null){
const parsedToDos = JSON.parse(savedToDos); // 살아있는 배열로 바꿈.
toDos = parsedToDos; // 배열에 기존 데이터 넣어서 보존.
parsedToDos.forEach(paintToDo);
}


5. Loading Todo

⭐️ array에 있는 각각의 item에 대해 함수 실행

forEach( )

ex) parsedToDos.forEach((item) => "This is" + item);
-> 입력값이 a,b,c일 시, This is a, This is b, This is c 출력.



6. Deleting Todo

📌 문제: 화면에서 삭제버튼 눌러도 새로고침 하면 다시 나타남

  • 이유 : localStorage에서는 지우지 않았기 때문.
    toDos array가 지워지더라도 localStorage에는 남아있다.

📌 어떤 item을 지울지 구분하기

  • ID를 부여해서 식별
    todo를 object 형태로 바꾸기

📌 array에서 요소를 삭제하고 싶을 때

  • 지우고 싶은 item을 제외한 새 array를 만듦.
  • filter( ) 사용 (forEach와 비슷함)

⭐️ filter( )

ex) arr.filter(item => item > 2)

array의 item을 유지하고 싶으면 함수는 반드시 true를 리턴해야 함.

-> false를 리턴하면 그 item은 새 array에 포함되지 않음.
-> 이 원리를 사용해서 요소 없애줌.


filter 예제

참고) Date.now()

: 밀리초를 주는 함수 -> 랜덤숫자 제공


최종 코드

JS

const toDoForm = document.getElementById("todo-form");
const toDoInput = document.querySelector("#todo-form input");
const toDoList = document.getElementById("todo-list");
let toDos = []; 
const TODOS_KEY = "todos"

function saveToDos(){
localStorage.setItem(TODOS_KEY, JSON.stringify(toDos));
}

function deleteToDo(event){
const delLi = event.target.parentElement; 
delLi.remove();
toDos = toDos.filter(todo => todo.id !== parseInt(delLi.id)); 
// localStorage에 선택한 요소만 삭제하고 다른 요소는 남겨둠.
// delLi.ld의 type은 string, todo.id의 type은 number 이므로
// delLi를 parseInt( )해주어 숫자로 바꿔줌.
saveToDos();
}

function paintToDo(newTodo) {
const todoLi = document.createElement("li"); 
todoLi.id = newTodo.id; // li에 id 부여 
const todoSpan = document.createElement("span"); 
todoSpan.innerText = newTodo.text; // 텍스트가 아닌 obj를 받기 때문에 newTodo.text로 바꿔야 입력값 잘 보임. 
const button = document.createElement("button"); 
button.innerText = "❌";
button.addEventListener("click", deleteToDo); 
todoLi.appendChild(todoSpan); 
todoLi.appendChild(button);
toDoList.appendChild(todoLi); 
}

function handleToDoSubmit(event) {
event.preventDefault();
const newTodo = toDoInput.value; 
toDoInput.value = ""; 
const newToDoObj = {  // object 만들기 
text:newTodo,
id: Date.now(), // 각각의 item 구별 
}
toDos.push(newToDoObj); // 배열에 object 저장  
paintToDo(newToDoObj); // object 보여주기  
saveToDos(); 
}

toDoForm.addEventListener("submit", handleToDoSubmit);

const savedToDos = localStorage.getItem(TODOS_KEY); // 입력값이 없을 때에는 null 출력됨.

if(savedToDos !== null){
const parsedToDos = JSON.parse(savedToDos); // 살아있는 배열로 바꿈.
toDos = parsedToDos; // 배열에 기존 데이터 넣어서 보존.
parsedToDos.forEach(paintToDo);
}

HTML

<form id="todo-form">
  <input type="text" placeholder="Write a To Do and press Enter" required>
</form>
<ul id="todo-list"></ul>
<script src="./app.js"></script>


출처: 노마드코더 바닐라 JS로 크롬 앱 만들기
profile
모든게 새롭고 재밌는 프론트엔드 새싹

0개의 댓글