상세 컨텐츠

본문 제목

[노마드코더] 바닐라JS 공부 7일차(To Do List)

Javascript

by 래모 2022. 1. 15. 22:32

본문

기본 세팅

// Setup 7.0

html

<!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">
    <title>Momentum App</title>
</head>
<body>
    <form id = "todo-form">
        <input required type="text" placeholder="Write a To Do and Press Eneter">
    </form>
    <ul id = "todo-list">
        
    </ul>
    <script src = "js/todo.js"></script>
</body>
</html>

js

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


function handleToDoSubmit(e) {
    e.preventDefault(); // 새로고침 방지
    const newTodo = toDoInput.value;
    toDoInput.value = "";
}

toDoForm.addEventListener("submit", handleToDoSubmit)

 

목록 추가하기

// Adding ToDos 7.1

✔ toDoInput의 value를 ul밑에 li태그로 감싼 형태로 추가해야함

자바스크립트를 이용해서 문서에 HTML 요소 추가하기

  • createElement() : 요소 생성
  • creteTextNode() : 텍스트 추가
  • appendChild() : 선택한 요소 안에 자식 요소 추가
const h1 = document.createElement("h1"); // <h1></h1>태그 생성
const Hi = document.createTextNode("Hi"); // "Hi" 문자열 생성
// h1.innerText = "Hi"와 동일함

h1.appendChild(Hi); // <h1>Hi</hi> 
document.body.appendChild(h1); // html에 h1 생성

 

결과

 

목록 요소 삭제하기

// Deleting To Dos 7.2

✔ 버튼을 생성해서 그것을 누를시 해당 <li>태그 삭제하기 

 

x가 눌러진 곳이 어딘지 찾는것이 관건!

=> 함수가 실행된 event의 타겟을 찾고 그 타겟의 부모를 찾아서 remove함

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

 

this를 사용해서도 바꿀 수 있음

this키워드는 어느 언어에서든 자기 자신을 뜻함

button.addEventListener("click", deleteToDo)에서 읽혀져서 아래와 같이 작성 가능

function deleteToDo() {
    const li = this.parentElement;
    li.remove();
}

 

결과

 

 

목록 저장하기

// Saving To Dos 7.3

// Loading To Dos  7.4 7.5

✔ localStorage 사용 

localStorage는 string만 지원하기 때문에 배열을 문자열로 바꿨다가 다시 배열로 바꾸는 과정이 필요함

어떤 형태든 문자열로 바꾸기

: JSON.stringify()

const toDos = [];

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

배열형태의 문자열을 배열로 바꾸기

: JSON.parse("[1,2]") => [1,2]

 

배열 내의 각각 요소에 접근해서 함수 실행하기

: array.foreach(function)

click과 같은 이벤트 리스너를 제공해주듯이 JS는 item을 제공해서 현재 배열 안에 어떤 요소에 대해 접근하고 있는 지 알려줌

const savedToDos = localStorage.getItem(TODOS_KEY);

if (saveToDos) {
    const parsedToDos = JSON.parse(savedToDos);
    parsedToDos.forEach((item) => console.log("this is the turn of ", item));
    // parsedTodos.foreach(sayHello)
    // function sayHello(item) {
    //    console.log("this is the turn of ", item);
    // }와 동일한 방식
}

 

 

중복된 요소 구분해서 삭제하기

// Deleting To Dos 7.6 7.7

✔ 내용이 중복된 요소들도 존재할 수 있음 따라서 Date 객체를 이용해서 랜덤으로 id를 부여함

const newTodoObj = { // 각 요소들을 분리해주기 위해 id가 부여된 객체 생성
    text: newTodo,
    id: Date.now(),
};

toDos.push(newTodoObj); // newTodoObj를 배열에 저장

 

배열 내의 특정 item 삭제

:array.filter(function)

functino의 결과가 true면 배열에 남겨두고 false면 버림

const numbers = [1,2,3,4,5];
numbers = numbers.filter((item) => item !== 3 ); // 1,2,4,5

 

결과물

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

const TODOS_KEY = "todos";

let toDos = [];

function saveToDos() {
    localStorage.setItem(TODOS_KEY, JSON.stringify(toDos)); // localStorage에 문자열 형태로 넣어줌
}

function deleteToDo(e) {
    const li = e.target.parentElement; // 부모요소 얻기
    //const li = this.parentElement;와 같음
    
    li.remove(); // 해당 부모 요소 삭제
    toDos = toDos.filter((todo) => todo.id !== parseInt(li.id)); // 배열에서도 찾아서 삭제해줌
    saveToDos(); // 새로운 toDos로 저장
}

function paintToDo(newTodoObj) {
    const li = document.createElement("li"); // li태그 생성
    const span = document.createElement("span"); // span태그 생성
    const button = document.createElement("button"); // button 태그 생성

    span.innerText = newTodoObj.text; // span 내에 문구를 넣음
    button.innerText = "❌"; // button 내에 x를 넣음
    
    li.id = newTodoObj.id; // li태그에 id부여
    li.appendChild(span); // li로 span 감싸기
    li.appendChild(button); // li로 button 감싸기

    toDoList.appendChild(li); // todoList 안에 li 넣기

    button.addEventListener("click", deleteToDo); // click시 해당 목록 삭제
}

function handleToDoSubmit(e) {
    e.preventDefault(); // 새로고침 방지
    
    const newTodo = toDoInput.value; // todoInput의 value를 가져와서 저장
    toDoInput.value = ""; // 초기화시켜줌

    const newTodoObj = { // 각 요소들을 분리해주기 위해 id가 부여된 객체 생성
        text: newTodo,
        id: Date.now(),
    };

    toDos.push(newTodoObj); // newTodoObj를 배열에 저장

    paintToDo(newTodoObj); // newTodoObj를 목록에 추가함
    saveToDos();
}

toDoForm.addEventListener("submit", handleToDoSubmit); // 엔터키 누르면 함수 호출

const savedToDos = localStorage.getItem(TODOS_KEY); // localStorge에서 아이템 얻기

if (savedToDos !== null) { // 비어있지 않다면
    const parsedToDos = JSON.parse(savedToDos); // 배열로 바꿔줌
    toDos = parsedToDos; // toDos배열에 parsedToDos배열을 대입
    parsedToDos.forEach(paintToDo); // 각 요소에 대해 paintToDo함수 실행
}

관련글 더보기