본문 바로가기

Front-End

[JavaScript] To-do List 만들기 - 3 (목록의 요소 삭제하기, 체크박스 수정)

하고 싶은 일

1. 할 일을 입력 받음

2. 리스트에 올라감

3. 리스트의 테두리에 박스가 있었으면 좋겠음

4. 리스트의 마커가 체크박스였으면 좋겠음 

5. 체크박스가 checked 상태일 때 취소선이 생김

6. 목록에 있는 할일을 삭제할 수 있는 기능이 있었으면 좋겠음

7. html 파일과 js 파일이 나눠졌으면 좋겠음(refactoring)

 

목록의 요소 삭제하기

[취소선 만들기]에서 썼던 addEventListener()를 사용해서 delItem이라는 함수로 목록의 요소를 삭제할 수 있도록 했다.

1. function.bind(thisArg, arg1, arg2, ···)

bind 매서드를 사용하면, 함수의 컨텍스트를 변경하거나, 함수에 초기 인수를 설정하는 등의 작업을 할 수 있다.

 

여기에서 function은 delItem이 되고,

thisArg에는 null을 넣어서 this 값을 무시하고 사용할 수 있도록 했고,

arg1에 i를 넣어서 항목의 해당 인덱스를 함수에 전달할 수 있도록 해서 삭제 기능이 동작할 수 있도록 했다.

 

추가한 코드는 아래와 같다.

var del = document.createElement("button"); //삭제 버튼
todoItem.appendChild(del);
del.innerText = "X";

del.addEventListener("click", delItem.bind(null, i));
function delItem(index) {
  var listItem = list.children[index];
  // console.log(listItem);
  listItem.remove();
  todolist.splice(index, 1);
}

 

2. 수정 사항

' 체크 박스에 체크를 하고 새로운 항목을 추가하면 체크가 유지되지 않음 ' 오류가 발생하여 이를 해결하기 위해 상태를 유지하기 위한 코드를 추가했다.

if (todolist[i].deleted) {
  span.style.textDecoration = "line-through";
  checkbox.checked = true;
}

uploadTodoList 함수가 실행될 때마다 체크박스들이 다시 생성되면서 발생하는 문제임을 알게 되었다.

따라서 기존에 생성한 체크박스들은 유지를 하고, 새로운 항목을 추가할 때는 새로운 체크박스를 생성하지 않도록 코드를 수정했다.

 

3. 전체 코드

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Todo-List</title>
    <style>
      #wholeList {
        background-color: powderblue;
        padding: 5px;
        border: 2px solid lightgray;
        margin-left: 500px;
        margin-right: 500px;
        margin-top: 5px;
        padding-bottom: 5px;
      }
      #input {
        border-top: 1px solid lightgray;
        padding-top: 5px;
        margin-bottom: 0px;
      }
      #list {
        display: inline-block;
        text-align: left;
        padding: 5px 0px 5px 5px;
        margin-bottom: 5px;

        font-size: 24px;
      }
      body {
        text-align: center;
      }
      ul {
        list-style-type: none;
      }
    </style>
    <script>
      var todolist = [];

      function uploadTodoList() {
        var enrollText = document.getElementById("enrollText");
        var list = document.getElementById("list");

        var txt = enrollText.value;

        todolist.push({ text: txt, deleted: false });
        enrollText.value = null;

        list.innerHTML = "";

        for (var i = 0; i < todolist.length; i++) {
          var todoItem = document.createElement("li");
          var checkbox = document.createElement("input"); //체크박스
          var span = document.createElement("span"); // 글자

          checkbox.type = "checkbox";
          span.appendChild(document.createTextNode(todolist[i].text));
          todoItem.appendChild(checkbox);
          todoItem.appendChild(span);
          list.appendChild(todoItem);

          // X 버튼 만들기
          var del = document.createElement("button"); //삭제 버튼
          todoItem.appendChild(del);
          del.innerText = "X";

          console.log(list);

          if (todolist[i].deleted) {
            span.style.textDecoration = "line-through";
            checkbox.checked = true;
          }

          checkbox.addEventListener("change", doneTodo(i));
          del.addEventListener("click", delItem.bind(null, i));
        }
        function doneTodo(index) {
          return function () {
            var todo = todolist[index];
            todo.deleted = this.checked;
            var span = this.parentElement.querySelector("span");

            if (todo.deleted) {
              span.style.textDecoration = "line-through";
            } else {
              span.style.textDecoration = "none";
            }
          };
        }

        function delItem(index) {
          var listItem = list.children[index];
          // console.log(listItem);
          listItem.remove();
          todolist.splice(index, 1);
        }
      }
    </script>
  </head>
  <body>
    <h1>To-Do List</h1>
    <div id="wholeList">
      <ul id="list"></ul>

      <!-- 할일 입력하기 -->
      <div id="input">
        <input id="enrollText" type="text" />
        <input
          type="button"
          value="등록"
          onclick="
        uploadTodoList();
          alert('등록 완료!');
          "
        />
      </div>
    </div>
  </body>
</html>