[JavaScript] JS로 크롬 만들기 12. HTML element 삭제 localStorage 반영

작성:    

업데이트:

카테고리:

태그: , ,

todos item의 삭제

문제 상황 : 화면의 item을 삭제해도 localStorage에 있는 toDos의 항목은 삭제되지 않는다.

더 문제 상황 : 어떤 item을 지우는지 localStorage는 알 수가 없다.

해결 : 항목마다 ID를 부여하자.


array 대신 object로 저장

function handleToDoSubmit(event) {
  event.preventDefault();            // 기본동작 제거
  const newTodo = toDoInput.value;   // 입력값을 newTodo에 저장
  toDoInput.value = "";              // 입력공간 값 제거
  const newTodoObj = {               // object 정의
    text: newTodo,                   // newTodo의 key는 text
    id: Date.now(),                  // id를 Date.now()로 두어 랜덤 id 부여
  }
  toDos.push(newTodoObj);            // toDos array에 newTodoObj 추가
  paintToDo(newTodoObj);             // 입력값을 처리
  saveToDos();                       // Submit되면 ToDos를 저장하는 saveToDos 함수 호출
}
  • 고유 id를 부여하기 위해 Date.now() 사용
  • 이를 text와 함께 담기 위해 object로 저장
  • paintToDo에 object 전달


li에 id 지정

function paintToDo(newTodoObj) {
  // li와 span 정의
  const li =  document.createElement("li");          // document에 li 만들기
  li.id = newTodoObj.id;                             // li의 id를 newTodoObj의 id로 지정
  ...
}
  • object 전달받음
  • object의 id를 li에 id를 지정할 때 사용
  • li가 각각의 고유한 id를 가지게 되었음


filter() 함수

  • array.filter(function) 형태로 사용
  • array의 각 item에 대하여 function에서 true인 item들만 남겨 새 array 생성
  • item을 각각 처리한다는 점에서는 forEach() 함수와 비슷
    • forEach() : 각각의 item에 function 적용
    • filter() : true를 반환하는 item들만 모아 새 array 생성
function evenCheck(n){
  if (n % 2 === 0) {
    return true
  } else {
    return false
  }
}

const array = [1, 2, 3, 4].filter(evenCheck);
console.log(array);

// (2) [2, 4]


코드 적용

// js/todo.js
function paintToDo(newTodoObj) {
  ...
  // button 정의
  const button = document.createElement("button");   // document에 button 만들기
  button.innerText = "";                          // button에 'X' 표시 text 넣기
  button.addEventListener("click", deleteToDo);      // button클릭 시 deleteToDo 함수 실행
  ...
}

function deleteToDo(event) {
  const li = event.target.parentElement;             // 삭제해야 하는 li를 parentElement를 이용해 조회/저장
  // toDos 배열의 각각의 toDo에 대해 id가 li.id와 다른 것만 남긴다.
  // li.id는 string, toDo.id는 number 이므로 데이터타입 통일시키는 것에 주의
  toDos = toDos.filter((toDo) => toDo.id !== parseInt(li.id)); 
  li.remove();                                       // parentElement 제거 
  saveToDos();                                       // li를 제거한 toDos를 localStorage에 저장
}
  • X 버튼을 클릭하면 deleteToDo() 함수 실행
  • event.target의 parentElement를 통해 X의 부모 태그인 li 확인
  • 이 li의 id와 toDos 배열의 toDo 객체의 id 프로퍼티가 같은지 확인
  • 데이터타입이 li.id는 string이므로 parseInt() 함수 사용으로 자료형 통일
  • li.remove()하여 HTML 화면 상에서 제거
  • saveToDos()하여 li가 제거된 ToDos 배열을 localStorage에 저장


전체 JS 코드

// js/todo.js

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

const TODOS_KEY = "todos"
let toDos = [];             // 초기에는 빈 array, 그리고 바꿀 수 있도록 let 설정

function saveToDos() {
  localStorage.setItem(TODOS_KEY, JSON.stringify(toDos));    // localStorage에 todos라는 이름으로 toDos array 저장
}

function deleteToDo(event) {
  const li = event.target.parentElement;             // 삭제해야 하는 li를 parentElement를 이용해 조회/저장
  // toDos 배열의 각각의 toDo에 대해 id가 li.id와 다른 것만 남긴다.
  // li.id는 string, toDo.id는 number 이므로 데이터타입 통일시키는 것에 주의
  toDos = toDos.filter((toDo) => toDo.id !== parseInt(li.id)); 
  li.remove();                                       // parentElement 제거 
  saveToDos();                                       // li를 제거한 toDos를 localStorage에 저장
}

function paintToDo(newTodoObj) {
  // li와 span 정의
  const li =  document.createElement("li");          // document에 li 만들기
  li.id = newTodoObj.id;                             // li의 id를 newTodoObj의 id로 지정
  const span = document.createElement("span");       // document에 span 만들기       
  span.innerText = newTodoObj.text;                  // span에 newTodoObj의 text 넣기

  // button 정의
  const button = document.createElement("button");   // document에 button 만들기
  button.innerText = "";                          // button에 'X' 표시 text 넣기
  button.addEventListener("click", deleteToDo);      // button클릭 시 deleteToDo 함수 실행

  // span, button을 li에, li를 toDoList에 넣기
  li.appendChild(span);                              // li에 span을 넣기
  li.appendChild(button);                            // li에 button 넣기
  toDoList.appendChild(li);                          // toDoList ul에 li 넣기
}

function handleToDoSubmit(event) {
  event.preventDefault();            // 기본동작 제거
  const newTodo = toDoInput.value;   // 입력값을 newTodo에 저장
  toDoInput.value = "";              // 입력공간 값 제거
  const newTodoObj = {               // object 정의
    text: newTodo,                   // newTodo의 key는 text
    id: Date.now(),                  // id를 Date.now()로 두어 랜덤 id 부여
  }
  toDos.push(newTodoObj);            // toDos array에 newTodoObj 추가
  paintToDo(newTodoObj);             // 입력값을 처리
  saveToDos();                       // Submit되면 ToDos를 저장하는 saveToDos 함수 호출
}

toDoForm.addEventListener("submit", handleToDoSubmit);

function sayHello(item){                             // JS는 자동으로 item이라는 parameter 추가
  console.log('this is the turn of', item);
}

const savedToDos = localStorage.getItem(TODOS_KEY);  // localStorage의 toDos를 가져와 savedToDos에 저장

if (savedToDos) {                                    // savedToDos에 item이 있다면
  const parsedToDos = JSON.parse(savedToDos);        // parse한 것을 parsedToDos에 저장하고
  toDos = parsedToDos;                               // toDos에 parsedToDos를 저장
  parsedToDos.forEach(paintToDo);                    // 이 각각의 item에 paintToDo 함수 적용
}

댓글남기기