Vanilla Javscript 구현팁(Closest)


:raising_hand: 프론트엔드 개발관련 공부내용을 기록하는 포스트 입니다.


1. Closest


  • 전달받은 타겟 정보(클라이언트에서 받은 이벤트정보)가 발생 시 가장 가까운 특정 태그를 찾는방법

render 를 통해서 아래와 같이 태그가 추가된다.

image

const render = (menu) => {
    const template = menu
      .map((item, index) => {
        return `<li data-menu-id="${index}" class="menu-list-item d-flex items-center py-2">
                <span class="w-100 pl-2 menu-name">${item.name}</span>
                <button
                    type="button"
                    class="bg-gray-50 text-gray-500 text-sm mr-1 menu-edit-button"
                >
                    수정
                </button>
                <button
                    type="button"
                    class="bg-gray-50 text-gray-500 text-sm menu-remove-button"
                >
                    삭제
                </button>
                </li>`;
      })
      .join("");

이때 사용자는 수정, 삭제 버튼을 눌러서 이에 맞는 작업이 소스에서 실행되야하는데

image

위와 같이 여러개가 있다면 사용자가 어떤 항목의 수정,삭제를 눌렀는지 어떻게 알 수 있을까?

이에 대한 방안으로 closest 를 사용하였다.

const updateMenuName = (e) => {
  // classList 로 target(사용자가 클릭한 버튼 태그)에 Class들을 끌어오고
  // contains 로 해당 list 안에 포함되어 있는지 확인한다.
  if (e.target.classList.contains("menu-edit-button")) {
    // 사용자가 클릭한 태그에서 가장 가까운 li 태그로 올라가려면
    // closest 함수를 사용하면 된다.
    const menuId = e.target.closest("li").dataset.menuId;
    console.log(menuId);
    const $menuName = e.target.closest("li").querySelector(".menu-name");
    const changedMenuName = prompt(
      "수정할 메뉴명을 입력해 주세요",
      $menuName.innerText
    );
    console.log("hh" + JSON.stringify(this.menu));
    this.menu[menuId].name = changedMenuName;
    store.setLocalStorage(this.menu);
    $menuName.innerText = changedMenuName;
  }
};

updateMenuName 함수는 e(사용자 이벤트) 를 인자로 받고 해당 이벤트가 발생한 타겟을 대상으로 각각의 작업을 진행한다.

여기서 확인해볼 부분은

const $menuName = e.target.closest("li").querySelector(".menu-name");

이 부분인데 전달받은 e.target 에서 closest("li") 를 사용하게 되면 넘겨받은 이벤트 e.target 의 가장 가까운 li 태그를 찾았고 해당 태그의 menu-name class 값을 변수에 저장한다.

즉, 위와 같이 어떤 이벤트값에서 특정 태그를 찾고 싶을때 사용하면 되겠다.