todoList 버블링

이경준·2020년 12월 10일
0

todoList

목록 보기
2/8
post-thumbnail

todoList를 javascript로 프로젝트를 진행하던 중 리스트를 추가했을시 이벤트가 먹히지 않는 상황에서 시간을 많이 허비하였다.

이벤트 위임시 버블링이생겨 추가되는 요소의 이벤트도 가져올수 있다는 개념이 떠올라서 시도해 보았다.


HTML

<div id="todo-lists">
  
  <!--첫번째 리스트-->
  <div class="todo-list">
    <input type="checkbox" name="" id="" />
    <p>내용</p>
    <span>1</span>
    <div class="additional-list">
      <i class="fas fa-ellipsis-h additional-icon"></i>
      <div class="additional-pocket">
        <div class="delete-box">
          <i class="far fa-trash-alt"></i>
          <span>Delete</span>
        </div>
      </div>
    </div>
  </div>
  
  <!--두번째 리스트-->
  <div class="todo-list">
    <input type="checkbox" name="" id="" />
    <p>내용</p>
    <span>1</span>
    <div class="additional-list">
      <i class="fas fa-ellipsis-h additional-icon"></i>
      <div class="additional-pocket">
        <div class="delete-box">
          <i class="far fa-trash-alt"></i>
          <span>Delete</span>
        </div>
      </div>
    </div>
  </div>
</div>

가장 부모엘리먼트인 todo-lists에 클릭 이벤트를 적용하고, delete-box를 클릭시 todo-list를 제거할 예정이다.


1. 이벤트에 적용할 함수 만들기

//additional-pocket을 전부 지우는 함수
const deleteAllAdditionalPocket = () => {
  const additionalPockets = document.querySelectorAll(".additional-pocket");

  additionalPockets.forEach(function (pocket) {
    pocket.style.display = "none";
  });
};

//additional-pocket 디스플레이 toggle함수
const todoListEditDisplayToggle = (event) => {
  const currentAdditionalPocket = event.target.nextElementSibling;

  if (event.target.className === "fas fa-ellipsis-h additional-icon") {
    if (window.getComputedStyle(currentAdditionalPocket).display === "none") {
      deleteAllAdditionalPocket();
      currentAdditionalPocket.style.display = "block";
    } else {
      currentAdditionalPocket.style.display = "none";
    }
  }
};

1) 클릭시 나머지 additional-pocket들을 모두 제거하기 위하여 deleteAllAdditionalPocket함수를 만들었다.

2) 클릭할때마다 appear/disappear을 반복하게 하기위하여 todoListEditDisplayToggle함수를 만들었다.

3) (추가되는 리스트에도 적용할 수 있도록) 부모 함수에 이벤트를 줄것이기 때문에 클릭이벤트는 투두리스트의 모든 태그에 적용 될 것이다. 아이콘에만 함수를 적용하기 위하여 if문을 이용하여 className으로 1차 확인을 한다.

3) if문을 다시한번 사용하여 2차로 display를 확인하여 반대로 움직일 수 있게 적용하였다.


2. delete버튼 클릭시 리스트 삭제하는 함수 만들기

const deleteTodoListClickHandeler = () => {
  const deleteButton = document.querySelectorAll(".delete-box");
  deleteButton.forEach(function (deleteBtn) {
    deleteBtn.addEventListener("click", function (event) {
      event.stopPropagation();

      //TODOS에서 삭제
      DeleteListFromTODOS(event);

      //HTML에서 삭제
      deleteListFromHTML(event);
      return;
    });
  });
};

1) delete버튼 클릭시 데이터와 html에서 삭제하는 함수이다.

2) 부모태그에 이벤트를 주고 그안에 다시 이벤트를 주기 때문에 자식으로부터 부모로 이벤트가 올라가는 버블링이 생겨날 것이다. delete버튼을 클릭했을때 자식이벤트만 작동하게 하기위하여 event.stopPropagation()을 적용하였다.


3. 클릭이벤트 최종

const editTodoListClickHandeler = () => {
  todoListContainerElement.addEventListener("click", (event) => {
    //additional-pocket 디스플레이 유/무
    todoListEditDisplayToggle(event);
    //리스트 삭제 클릭이벤트
    deleteTodoListClickHandeler();
  });
};

결론) 부모태그에 이벤트를 적용하면 새로생기는 자식 태그에 이벤트를 자연스럽게 적용할 수 있다. 그러나 자식태그에 이벤트를 적용할시 버블링이 생기는 것을 주의하여야한다.

profile
내가 기억하기위한 블로그

0개의 댓글