[JavaScript] ToDo리스트 만들기


1️⃣ 목표

  • 이번에는 ToDo리스트기능을 구현해볼 예정입니다.
<form id="A17-todo">
  <input type="text" placeholder="what to do" required />
</form>
<ol id="A17-todo-list"></ol>
  • html의 기본 형태는 위와 같습니다. todo(할 것)submit으로 받기 위해 form태그를 사용하여 입력을 받았습니다.
  • 입력받은 값ol(번호가 달린 리스트)태그안에 li(리스트)형태로 순차적으로 추가됩니다.
  • 새로고침이후에도 정보가 유지되기 위해 LocalStorage를 임시로 이용할 계획입니다.

2️⃣ 새롭게 배운 주요기능들

(1) 배열 push()함수

  • 새로고침이후에도 Todo리스트가 유지되기 위해서는 LocalStorage를 이용해야 합니다. 즉, 이전에 배운 localStorage.setItem()이용하여 입력받은 값을 일리리 저장해주는 과정이 필요합니다.
  • 추가로 리스트 제거, 리스트 완료표시기능도 넣어야 되기 때문에 배열형태로 저장해야합니다.
let toDos = [];
const toDoInput = document.querySelector("#A17-todo input");

function submitFunc(event)
    event.preventDefault();
    const newInput = toDoInput.value;
    const newObj = {
        text: newInput,
        id: Date.now(),
        is_done: false,
    }
    toDoInput.value = "";
    toDos.push(newObj);
    saveToDos();
    paintToDo(newObj);
}

/* saveToDos() */
function saveToDos() {
    localStorage.setItem(TODO_KEY, JSON.stringify(toDos));
}
  • 위처럼 입력값에 대한 정보가 닯긴 배열(newObj)local storage로 최종적으로 넘겨줄 배열(toDos).push()메소드를 이용하여 추가해 줍니다.
  • id값은 현재시간을 (ms)단위로 변환한 값을 주는 Date.now()를 이용했습니다.
  • saveToDos()메소드에서는 최종적으로 local storage로 데이터를 넘겨주게 됩니다.

(2) JSON.stringify()

  • 위에서 local storage로 데이터를 넘겨주기 위해 toDos배열을 JSON.stringify()메소드로 포맷팅을 해준뒤 넘겨주었습니다.

  • 여기서 JSON은 “키-값 쌍”으로 이루어진 데이터 오브젝트를 전달하기 위해 인간이 읽을 수 있는 텍스트를 사용하는 개방형 표준 포맷입니다. 자세한 설명은 아래의 사이트를 참고면 됩니다.
    👉🏻 👉🏻 👉🏻 JSON - 위키백과 👉🏻 👉🏻 👉🏻 JSON개념 - 드림코딩 by 엘리

  • 포매팅을 해주지 않으면 다음과 같이 object로 표시되어 어떤 값이 저장되어있는지 확인하기 힘듭니다. (정상적으로 작동하기는 하다) before format

  • console.log() 출력값은 다음과 같습니다.

포매팅하지않은 toDos 콘솔출력
{text: "sample", id: 1629291987284, is_done: false}

JSON.stringify()사용후 toDos 콘솔출력
{"text":"sample","id":1629291987284,"is_done":false}

before format

  • 위와 같이 알아볼 수 있는 값으로 성공적으로 표시 되었습니다.

(3) forEach()

const savedToDos = localStorage.getItem(TODO_KEY);

if (savedToDos !== null) {
  const parsedToDos = JSON.parse(savedToDos);
  toDos = parsedToDos;
  parsedToDos.forEach(paintToDo);
}
  • 새로고침했을때 마다 위의 로직이 실행되어 LocalStorage에서 데이터를 가져와서 파싱해줍니다.
  • JSON에서 parse()stringify()와 반대로 JSON 문자열의 구문을 분석하고, 그 결과에서 JavaScript값이나 객체를 생성합니다.

savedToDos 콘솔출력
[{"text":"a","id":1629293013701,"is_done":false}]

JSON.parse사용후 콘솔출력
console out

  • parse파싱이 완료된 parsedToDos는 배열형태입니다. forEach()메소드를 이용하면 배열의 모든 요소인자로 받은 메소드를 호출해줍니다.
  • 노드메소드매개변수로 자동으로 넘겨줍니다.

(4) filter()

function deleteToDo(event) {
  const target = event.target.parentElement;
  target.remove();
  toDos = toDos.filter((toDos) => toDos.id !== parseInt(target.id));
  saveToDos();
}
  • 삭제버튼을 누르는 이벤트를 하면 deleteToDo()메소드를 호출합니다.
  • event.target는 버튼의 태그인 <button>을 가리키고 event.target.parentElement는 취소버튼의 부모노드<li>를 가르키게 됩니다. 즉, <li>event.target.parentElement를 삭제해야 정확히 리스트를 한개 삭제할 수 있습니다.
  • 하지만 역시 LocalStorage에서의 데이터도 업데이트 시켜줘야 합니다.
  • filter()메소드를 이용하면 forEach()메소드와 같이 배열의 모든 요소마다 특정 메소드를 호출하여줍니다. 만약 특정 메소드false(거짓)이 아닌 true(참)을 반환한 값들만을 모아둔 배열을 만들어 반환합니다.
  • 타겟노드는 바뀌지않고 반환값으로만 변환된 배열을 얻을 수 있습니다. 그러므로 toDos변수로 다시 받아줍니다.
  • filter()메소드는 위와같이 =>기호를 이용하여 메소드 대신 간단한 boolean형 조건문으로 대체 가능합니다.

3️⃣ 취소선으로 체크기능 넣기

(1) css, html

  • 취소선을 만들 수 있는 것은 htmlcss모두 기능이 있습니다.
    1. html에서 태그<s>로 바꾸기
    2. css에서 text-decoration요소 이용하기
  • 위의 방법중 html를 수정해주는 코드는 자바스크립트에서 노드HTML요소를 수정하는 방법으로 바꿔줄 수 있습니다. 하지만 이런식으로 태그를 변경해주면 기존에 있던 이벤트함수이 원하는데로 작동하지 않는 현상이 발생했습니다. (어떻게든 이벤트함수가 동작하도록 만들 수 있지만 코드가 너무 복잡해짐)
  • 또한 인터넷상에서도 css에서 구현된 기능은 되도록이면 js대신 css를 이용하는 것이 효율적이라고 말합니다.
/* style.css */
.A17-del {
  text-decoration: line-through;
  color: red;
}
/* todo.js */
function doneFunc(event) {
  const tar = event.target.parentElement;
  for (const i in toDos) {
    if (toDos[i].id === parseInt(tar.id)) {
      if (toDos[i].is_done === true) {
        event.target.classList.remove("A17-del");
        toDos[i].is_done = false;
      } else {
        event.target.classList.add("A17-del");
        toDos[i].is_done = true;
      }
    }
  }
  saveToDos();
}
  • css를 이용하면 위의코드만으로 간단하게 기능을 구현할 수 있습니다.

4️⃣ 최종 결과물

  • todo(할 것)최대 40자까지 작성하여 추가할 수 있습니다.
  • todo(할 것)클릭하여 체크선을 그리거나 지워줄 수 있습니다.
  • X 버튼을 눌러서 특정 todo(할 것)을 지울 수 있습니다.




© 2021.02. by kirim

Powered by kkrim