본문 바로가기

자바스크립트

JS) remove() 와 removeChild()

발단

바닐라 자바스크립트로 이것저것 만지던 중, 이벤트 위임으로 todo-list를 만들어보자 생각이 들었다.

그러던 중 예상치 못한 동작이 발생했다.

 

전개

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script defer src="app.js"></script>
    <link rel="stylesheet" href="style.css" />
  </head>
  <body>
    <div id="container">
      <div id="todo-lists"></div>
      <div id="form-wrapper">
        <form id="form">
          <input type="text" placeholder="Enter todo" name="todo_input" />
          <button>Enter</button>
        </form>
      </div>
    </div>
  </body>
</html>

 

const form = document.getElementById("form");
const wrapper = document.getElementById("todo-lists");

function handleTodo(e) {
  e.preventDefault()
  const btn = e.target.closest("button");
  if (!btn) return; //버튼을 누른게 아님
  const todo = e.currentTarget; // submit의 const todo

  if (btn.innerText === "remove") {
    wrapper.remove(todo);
  } else if (btn.innerText === "edit") {
    const todo_text = todo.querySelector("div");
    console.log(todo_text);
    const new_input = document.createElement("input");
    new_input.value = todo_text.innerText;
    todo.prepend(new_input);
    todo.remove(todo_text);
  }
}

function submit(e) {
  e.preventDefault();
  const value = form.elements["todo_input"].value;
  const todo = document.createElement("div");

  todo.addEventListener("click", handleTodo);

  const todo_text = document.createElement("div");
  const del = document.createElement("button");
  const edit = document.createElement("button");
  del.innerText = "remove";
  edit.innerText = "edit";
  todo_text.innerText = value;

  todo.appendChild(todo_text);
  todo.appendChild(del);
  todo.appendChild(edit);
  wrapper.appendChild(todo);
  e.target.elements["todo_input"].value = "";
}

form.addEventListener("submit", submit);

 

 

간단하게 말하면 텍스트를 입력하면 submit()함수에서 투두 리스트를 생성한다. 이때 todo라는 div태그 변수에 handleTodo이벤트를 연결한다.

이때 이벤트 위임으로 어느 버튼을 눌렀는지 확인하여 그 버튼에 맞는 액션을 작성했다.

 

 

위기

그런데 예상치 못한 동작이 발생한다.  edit을 누르면 해당 todo가 사라지고 delete를 누르면 id가 todo-lists인 div가 사라진다.

왜 이렇게 동작하는지 한참을 찾았다. 혹시 내가 이벤트 위임에 대해 잘못알고 있거나 모르는 기능이 있는 것일까...하는 애꿎은 closest만 건드리며 생각에 잠겼다.

 

도무지 답을 찾을 수 없어서 스택오버플로에 도움을 요청했다.

https://stackoverflow.com/questions/78312220/when-i-press-edit-the-to-do-list-item-disappears-and-when-i-press-delete-the

 

When I press edit, the to-do-list item disappears, and when I press delete, the id todo-lists disappears

I'm trying to create a simple to-do list app to practice JS. Each to-do-list has two buttons, and the button behavior I'm trying to implement via event deregulation. However, when I press edit, the...

stackoverflow.com

 

 

결말

 

El.remove()와 El.removeChild()를 헷갈린거 같다고 댓글이 달렸다.

저 댓글이 달리자마자 바로 알아보았다.

El.remove()는 노드에서 삭제하는 것이다. 즉 메모리에서 삭제한다. 내가 원하는건 El의 자식요소를 삭제하는 것이다. 

 

parentNoe.remove()대신 parentNode.removeChild(텍스트 div)를 선택해야한다. remove()를 사용하면 delete에선 wrapper를, edit에서는 todo라는 항목을 사라지게 만드는 것이다.

 

 

 

요약

가장 기본중 기본인 바닐라 자바스크립트를 헷갈려버렸다.

그러나 이번 기회에 바닐라 자바스크립트로 앱을 작성하기에 부족하다는 것을 깨달았다. 기본을 헷갈렸다는 것은 매우 부끄럽지만 이런 부끄러움을 숨기지 말고 내보여야 계기가 되어 성장할 수 있다고 믿는다. 그래서 블로그에 포스팅을 결정했다.