ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • getElementsByClassName이 안 돼서 이벤트 버블링으로 해결
    JS 2025. 11. 17. 23:31

     

     

    🏁 오늘의 문제 (251117)

     

    이벤트리스너를 배우고 실습문제를 푸는 중 아래와 같은 상황이 생겼다.

     

    문제상황

    getElementsByClassName으로 li를 찾아서 거기다 addEventListener을 걸은 것이다.

    const li = document.getElementsByClassName("item");
    li.addEventListener("click", ...);  // ❌ 에러!​

     

    알고보니 getElementsByClassName은 [item1,item2,...]같은 배열같은 값 (유사배열객체)을
    반환하는데 찐 배열은 아니고 이것을 HTMLCollection이라고 한다.

    HTMLCellection 자체에는 addEventListener 메소드가 없어서 바로 달지 못한다.

     

    그럼 언제 addEventListener가 바로 먹힐까?

    // 1. getElementById - 요소 1개
    const el = document.getElementById("my-id");
    el.addEventListener("click", ...);  // ✅
    
    // 2. querySelector - 요소 1개 (첫 번째 것만)
    const el = document.querySelector(".item");
    el.addEventListener("click", ...);  // ✅
    
    // 3. 직접 선택
    const el = document.body;
    el.addEventListener("click", ...);  // ✅

     

    덕분에 이벤트리스너는 요소가 한개만 선택되었을 때 다이렉트로 걸수있단것을 알수있었다.

     

     

    내가 생각한 문제해결 방법

    See the Pen Untitled by 배근영 (@lyla-bae) on CodePen.

    const ul = document.getElementById("arr-list-container");
    
    ul.addEventListener("click", function(e) {
      if (e.target.classList.contains("item")) {
        e.target.style.backgroundColor = 
          e.target.style.backgroundColor === "white" ? "" : "white";
      }
    });

     

    쨌든 문제를 해결하기위해 잔머리를 굴리다가 ul에 이벤트 핸들러를 걸고, 이벤트 버블링을 이용했다.

    li를 클릭하면 이벤트가 부모인 ul로 전파(버블링)되기 때문에, ul에 달린 이벤트 핸들러로 li 클릭을 감지할 수 있다.

     

    그런데 여기서 내가 클릭한 li만 스타일이 변경되어야 하는데  ul이 같이 걸리는 또하나의 문제가 발생한다.

    if문과 매개변수 e.target을 활용해 내가 현재 마우스로 클릭한 li만 스타일을 변경할수있게 짰다.

     

     

     

    여기서 e.target같은 특수한 이벤트 함수들이 궁금해 따로 개념을 더 잡아주었다.

    코딩애플 JS 기초강의에서 캡쳐해왓읍니다. 유료강의이니 다들 돈주고 들읍시다

    .target 실제로 클릭한 요소
    .currentTarget 지금 이벤트리스너가 달린곳
    .preventDefault() 이벤트를 기본동작을 막아줌
    .stopPropagation() 상위요소까지 이벤트버블링을 막아줌

     

     

     

    한단계 더 응용해보자면?

    문제 요구사항을 넘어섰기때문에 필요없지만 그래도 알아두면 좋을거같아서~~

    코딩애플 강의를 듣다가 알게되었는데 바로 dataset을 활용하는것이다.

    <div data-데이터이름="값"></div> //이렇게 적으면
    document.querySelector().dataset.데이터이름; // 이렇게 가져오기 가능

     

    이렇게 태그에 data- 속성을 추가하면,,,

     

     

     

    // HTML
    `<li class='item' data-index='${index}'>${item}</li>`
    
    // JS
    itemWrap.addEventListener("click", function(e) {
      if (e.target.dataset.index !== undefined) {
        const index = e.target.dataset.index;
        
        // 🎯 이게 포인트!
        console.log(`클릭한 항목: ${arr_list[index]}`);
        console.log(`위치: ${index}번째`);
        
        e.target.style.backgroundColor = 
          e.target.style.backgroundColor === "white" ? "" : "white";
      }
    });

     

    이런식으로 index값을 따로 부여해서
    '몇 번째 li인지', '어떤 데이터를 가진 li인지' 같은 추가 정보를 저장하고 활용할 수 있다.

     

    'JS' 카테고리의 다른 글

    Fetch와 Promise  (1) 2025.11.25
    호이스팅과 var/let/const 차이점  (0) 2025.11.20
    API 그것이 뭐길래  (0) 2025.11.19
    나빼고 다 아는 JS 기초 - 조건문, 객체, 자료구조  (0) 2025.11.13
    클로저와 스코프  (5) 2025.08.12
Designed by Tistory.