JavaScript 이벤트 관련 질문입니다. hidden 속성을 제거했는데 화면에 계속 남아 있어요.

조회수 903회

(미션4-5) https://codepen.io/kkndyo/pen/mjdqmN 중 function closeDetail(e) 미션 4-5 중 아이템 소개 패널 닫기버튼을 눌렀을때, 정상적으로 부모 노드에 hidden 속성이 다시 추가되고 is-active 클래스리스트가 삭제된 것을 console.log를 통해 확인했는데 화면에서는 사라지지 않고 그대로 남아있습니다.

이유가 무엇인가요?

  • (•́ ✖ •̀)
    알 수 없는 사용자

1 답변

  • 안녕하세요. 진호님 ^ ㅡ ^

    질문에 답변 드립니다.

    문제 발생 원인

    <li> 요소에 이벤트를 걸었기 때문입니다. .button.is-close-panel 버튼이 포함되어 있어, 버튼을 클릭할 때 마다 <li> 요소로 이벤트 전파(Propagation) 됩니다.

    그래서 버튼을 눌러 closeDetail()를 수행해도, 바로 <li> 요소에 연결된 showDetail() 함수가 실행되니 사라지지 않는 것처럼 보이는 것이죠.

    // <li> 요소 탐색 참조
    var aList = aContext.querySelectorAll(".ediya-menu__item");
    
    for (var i = 0; i < aList.length; i++) {
      // <li> 요소에 이벤트 바인딩
      aList[i].addEventListener("click", showDetail.bind(this, i));
    }
    
    // <li> 요소가 클릭 될 때 마다 이벤트가 발생!!!!
    function showDetail(index, e) {
      e.preventDefault();
      var dtl = document.querySelectorAll(".ediya-menu__item--detail");
      dtl[index].hidden = false;
      dtl[index].classList.add("is-active");
    }
    

    주의! <li> 요소는 비 포커스 요소로 클릭 이벤트를 연결하면 접근성 이슈가 발생합니다.

    문제 해결책

    2가지 해결책을 이야기 드려봅니다. 권장되는 방법은 접근성이 고려된 2번째 방법입니다.

    해결책 1

    버튼 클릭 시, 부모 요소 <li>로 이벤트 전파를 차단합니다.

    function closeDetail(e) {
    
      // 이벤트 전파 중지: 
      // 부모 요소로 이벤트가 전파되는 것을 멈춥니다.
      e.stopPropagation();
    
      var parent = this.parentNode;
      parent.hidden = true;
      parent.classList.remove("is-active");
    }
    
    해결책 2

    <li> 내부에서 <a> 요소를 찾아 이벤트를 연결합니다. <li> 요소에 이벤트를 연결한 것이 아니기에 이벤트 전파에 영향을 받지 않습니다.

    for (var i = 0; i < aList.length; i++) {
      // <li> 내부의 <a> 요소에 이벤트를 바인딩 합니다.
      aList[i].querySelector('a').addEventListener("click", showDetail.bind(this, i));
    }
    

    주의! 현재 작성된 마크업 에서 <a> 요소는 단 하나만 존재해 별도의 식별자를 사용하지 않았지만, 별도의 식별자를 사용해 구분하는 것이 좋습니다.

    • (•́ ✖ •̀)
      알 수 없는 사용자

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)