Notice
Recent Posts
Recent Comments
Link
관리 메뉴

윤일무이

[노마드코더 바닐라JS로 크롬 앱 만들기] #7.0 ~ #7.8 본문

👋🏻 JavaScript/💭 노마드코더 바닐라JS

[노마드코더 바닐라JS로 크롬 앱 만들기] #7.0 ~ #7.8

썸머몽 2023. 3. 8. 22:54
728x90

📌 to do list 만들기

본격적으로 졸업과제의 핵심인 to do list를 만들어보았다.

여러 가지 기능이 짬뽕되어 있어 한 번에 이해하기가 어려웠다.

그러니까 복습하는 거지만.

 

HTML

<form id="todo-form">
        <input type="text" placeholder="Write a To Do and Press Enter" required />
    </form>
    <ul id="todo-list"></ul>

id가 todo-form이라는 form을 만들었고, 그 안에 input 타입이 text인 놈을 만든 후 밖에는 id가 todo-list인 ul을 만들었다.

 

JS

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;
    console.log(toDoInput.value);
    toDoInput.value = "";
    console.log(newTodo, toDoInput.value);
}

toDoForm.addEventListener("submit", handleToDoSubmit);

JS에서는 form과 input, list를 모두 잡아줬다.

이 form에 무언가가 제출될 때 handleToDoSubmit이라는 함수가 작동된다.

이 함수는 일단 제출할 때 디폴트인 새로고침을 방지해준다. (event라는 매개변수 적어주기)

이후 Input에 있는 value를 newTodo라는 변수에 저장해주고 리셋된 것처럼 블랭크를 보여주게 만든다.

 

저장한 이 값을 보여줄 수 있는 새로운 함수 paintToDo를 만든다.

function paintToDo(newTodo) {
  const li = document.createElement("li");
  const span = document.createElement("span");
  li.appendChild(span);
  span.innerText = newTodo;
  toDoList.appendChild(li);
}

newTodo를 인수로 하는 paintToDo는 작동될 때마다 li와 span을 만든다.

li 밑에 span이 위치할 수 있게 appendChild를 해주고, span에 입력한 newTodo가 나오게 한다.

이 구조가 ul, toDoList 밑으로 들어간 형태다.

 

  • newTodo
  • newTodo1

 

ul > li > span > input값

이런 구조라고 이해했다.

 

그런데 문제는 새로고침을 하면 모두 리셋되고, 가장 큰 문제인 잘못 입력했을 때 삭제가 안된다는 것이다.

이 부분을 수정하기 위해 먼저 삭제하는 기능을 구현한다.

 

 

📌 to do list 삭제하기

function paintToDo(newTodo) {
	const li = document.createElement("li");
    const span = document.creatElement("span");
    span.innerText = newTodo;
    
    const button = document.creatElement("button");
    button.innerText = "❎";
    button.addEventListener("click", deleteToDo);
  	li.appendChild(span);
  	li.appendChild(button);

    toDoList.appendChild(li);
}

JS에서 button을 만들어준다. 버튼 안에는 이모지가 들어간다.

  • 안녕
  • 잘가

이런 형태라고 해야 하나. list 안에 span과 button이 들어 있고 span에는 입력한 to do 가 들어 있는 상태다.

저 이모지를 누르면 to do 가 삭제되게끔 deleteToDo라는 함수를 만든다.

 

근데 이모지를 눌러서 삭제를 하려고 하면 문제가 발생한다.

버튼이 클릭되는 건 알겠는데 내가 삭제하고 싶은 to do가 뭔지 컴퓨터가 이해하지 못한다는 것이다.

내가 삭제하고 싶은 to do 가 가진 값을 찾아본다.

 

우리는 버튼에 대한 정보, 그러니까 내가 누른 버튼에 대한 정보를 알면 내가 어떤 to do 를 삭제하고 싶은지를 알 수 있다.

이를 버튼에 대한, 부모 정보를 찾는다고 표현하는데 이벤트의 타겟(버튼 클릭)의 부모 요소를 찾으면 된다.

 

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

deleteTodo는 클릭이 일어난 이벤트를 매개 변수로 하고 있으며, 이 이벤트 타겟의 부모 요소를 지우는 함수다.

내가 누른 버튼의 부모를 찾고, 그 부모 요소를 지워주는 것이다.

처음부터 이런 생각 나지 않고, 나중에도 이런 생각은 잘 나지 않는다.

그냥 이런 방법이 있구나 정도로 이해하고 넘어가면 좋겠다.

 

(니꼬샘... 도대체 이런 생각을 어떻게 하신건데요...)

 O

   o

 

 

📌 to do list 저장하기

삭제하기 전 문제가 하나 더 있었는데 바로 새로고침하면 적은 to do 가 모두 리셋된다는 거였다.

이걸 해결하기 위해 localStorage를 활용했다. (greeting 부분과 비슷한데 문제는 내가 그 부분에서 영혼이 나갔다는 것임)

 

먼저 toDo를 저장해야 한다.

이를 위해 toDos 라는 Array를 만들었다.

newTodo가 들어올 떄마다 이를 빈 Array에 추가하기 위해 toDos.push(newTodo) 라고 작성해주었다.

현재까지 to do 리스트를 입력하면 Array에 추가되는 형태까지 구현했다.

 

그러나 새로운 문제 (😭)localStorage는 Array를 저장할 수 없다는 것이다.이 놈은 문자열만 저장할 수 있어서, 우리는 JS에서 문자열로 변환시켜주는 JSON.stringify()를 사용했다.새로운 to do가 저장된 Array를 문자열로 바꿔준 후 localStorage에 저장했다.이제 이 저장된 내용이 화면에도 보이면 된다. 

 

const TODOS_KEY = "todos";

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

 

화면에 보이게 하려면... 반대로 문자열이 Array로 변환되면 된다 ^^;이를 위해 JSON.parse() 를 사용한다. 이걸 사용하면 배열 형태(object 타입)으로 불러와 저장된다.이 배열 형태를 .forEach() 를 써서 배열 형태의 각 요소들을 출력시키면 된다.

 

const savedToDos = localStorage.getItem(TODOS_KEY);

if (savedToDos !== null) {
  const parsedToDos = JSON.parse(savedToDos);
  parsedToDos.forEach((item) => console.log("this is the turn of ", item));
}

 

saveToDos함수 안에는 localStorage에 저장된 놈들이 문자열 형태로 저장된다.

이놈들을 savedToDos라고 선언하고, 여기에 값이 있다면 이 문자열 형태를 배열 형태로 바꿔준다.

그렇게 바꾼 놈들(Array에 들어 있었던 것들)을 하나씩 꺼내주면 this is the turn of [안에 있던 놈] 이렇게 출력된다.

 

바꿨다 다시 바꿨다 난리 부르스 치는 중... ^^!

 

 

📌 to do list 저장하기2

네 아직 안 끝났읍니다... 기쁨도 잠시 또 다른 문제 발생 ㅎㅎ

새롭게 추가되는 게 아니라 자꾸 이전의 것을 덮어 씌우는 문제가 발생한다.

 

이는 우리가 처음에 Array를 설정할 때 const toDos = [] 로 설정했기 때문이었다.

이게 왜 문제냐면 newToDo를 작성해 submit할 때마다 빈 어레이에 푸시를 하게 되고,

새로운 toDo들만 포함하고 있는 어레이를 저장하기로 해놔서 전의 toDO는 갖고 있지 않게 된 것이다.

 

즉 어레이를 const가 아닌 let으로 바꾸어 업데이트가 가능하도록 바꿔주고,

localStorage에 toDos가 있으면 갖고 있는 toDo를 복원하게 만들어준다.

 

const savedToDos = localStorage.getItem(TODOS_KEY);
if (savedToDos !== null) {
    const parsedToDos = JSON.parse(savedToDos);
    toDos = parsedToDos;
    parsedToDos.forEach(paintTodo);
}

 

대가리만 극지 말고 코딩을 해

 

...그거 어떻게 하는 건데...

 

이번 강의의 가장 큰 패착은 변수 이름이 다 비슷비슷해서 죽겠다는 것... ^^

 

 

📌 to do list 제대로 삭제하기

네 또 문제가 생겼음

to do를 지울 때마다 local storage에 업데이트가 되지 않는다......

아까 어떤 놈을 지우는지 지워는 지는데 로컬에는 업데이트가 안되는 것이에요...

 

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

function paintToDo(newTodo) {
  const li = document.createElement("li");
  li.id = newTodo.id;
  const span = document.createElement("span");
  span.innerText = newTodo.text;
  
  const button = document.createElement("button");
  button.innerText = "❌";
  button.addEventListener("click", deleteToDo);
  
  li.appendChild(span);
  li.appendChild(button);
  toDoList.appendChild(li);
}
function handleToDoSubmit(event) {
  event.preventDefault();
  const newTodo = toDoInput.value;
  toDoInput.value = "";

  const newTodoObj = {
    text: newTodo,
    id: Date.now(),
  };
  toDos.push(newTodoObj);
  paintToDo(newTodoObj);
  saveToDos();
}
if (savedToDos !== null) {
  const parsedToDos = JSON.parse(savedToDos);

  toDos = parsedToDos;
  parsedToDos.forEach(paintToDo);
}

 

전체적으로 수정한 코드들...

 

그래서 이 to do 들에게 id를 주고, 로컬에서도 지우게끔 해준다. (li.id 와 remove 부분)

지우고 싶은 아이템만 빼고 새 어레이를 만드는 것이 삭제의 로직인데, 이를 위해 filter 함수를 사용한다.

 

function sexyFilter(item){return item !== 3 }

 

뭐 이런 식으로 이 필터는 item을 매개변수로, item이 3이 아니면 true를 리턴한다.

3이라면 필터에 걸려서 사라지는 구조다.

 

toDos = toDos.filter(toDo => toDo.id !== li.id);

내가 클릭한 li.id라면 필터에 걸려서 사라진다.

내가 클릭한 아이디가 아니면 남아 있는 것이다. (내가 삭제 버튼 안 누른 li는 남아 있는 형태)

 


 

몹시 힘들었다.............. ㅠ

아직도 마지막 부분은 잘 이해가 안된다.

어떻게 되긴 했고 어떻게 따라가긴 했는데 도저히 저런 생각이 나질 않음 :)

but... 일단 울면서 따라간다...

 

 

바닐라 JS로 크롬 앱 만들기 – 노마드 코더 Nomad Coders

Javascript For Beginners

nomadcoders.co

 

728x90