[ CSS ] 자식 요소 클릭 이벤트 막기

방충림·2023년 3월 11일
3

Catch the error

목록 보기
1/7
post-thumbnail

카테고리 바를 만들던 도중 발견한 오류다.

증상

카테고리의 각 항목을 클릭하면, 클릭한 항목의 배경이 생겨 선택되었다는 것을 보여주는 CSS다.

JS구조는 아래와 같다.

 categoryFilter.map((item, index) => (
     <Box
         key={index}
         ...
         onClick={(e) => {
                    setBtnActive(e.target.textContent);
                    }}
   className={btnActive === item.text ? "active2" : ""}

간단하다. map으로 뿌려준 각각의 item의 text값과, 내가 클릭한 항목의 text값이 같으면, 동적으로 클래스 명을 부여하는 방식이다.

하지만 위의 gif에서 보이듯이, 텍스트 부분이 아닌 색깔도형 (mui에서 div같은 태그임)나 텍스트의 살짝 옆 여백을 누르면 배경이 사라지는 오류가 발생하였다.

원인

원인을 찾기위해 클릭 이벤트를 console.log(e.target.textContent)로 찍어보았다.

위 결과는 카테고리의 맨 왼쪽 색깔도형부터 맨오른쪽 텍스트부분까지 순차적으로 클릭해본 결과이다.

보다시피 색깔도형을 클릭할 때만 값이 출력되지 않음을 알 수 있다.

원인은 내가 에 부여한 onClick event를 자식 요소들에게까지 적용됐기 때문이다. 이를 event전파 또는 버블링 이라고 하나보다.

해결 방법 1

e.currentTarget 을 사용한다.

e.target은 부모 요소로부터 이벤트가 전파되어 실제 이벤트가 발생한 자식요소가 클릭되는 반면, e.currentTarget는 클릭이벤트를 걸어놓은 요소만을 가르킨다.

하지만, 나는 Text의 값이 필요하다. e.currentTarget의 값은 null로서, e.target처럼 부모노드로 넘어갈 수 없었다.

참고문헌 개인블로그


해결 방법 2

e.stopPropagation( ); 을 사용한다.

이는 현재 발생한 이벤트 이후의 이벤트들을 막아주는 메서드라고한다.
즉 버블링을 멈춰주는 메서드다.

하지만 이를 사용하였을 때 자식요소의 이벤트가 아예 사라져서, 자식요소 클릭 시 아무것도 클릭되지 않았다. 내가 원하는 것은 자식 요소를 클릭했을 때 부모요소의 이벤트가 뜨고, 그 이벤트의서 event.target을 통해 text값에 접근하는 것이다.

참고문헌 개인블로그


해결 방법 3

Text대신 key값인 Index를 사용해본다.

이 방법은 css단 해결방법은 아니지만, 근본전인 해결책을 줄 수 있을 듯하다. 왜냐하면, text는 눌러야만 출력 텍스트를 눌러야만 되는 반면 index는 map으로 뿌려지는 요소들 모두가 공통적으로 가지고 있는 요소이기 때문이다.

categoryFilter.map((item, index) => (
   <Box
       key={index}
       ...
       onClick={(e) => {
                  setBtnActive(index);
                  }}
 className={btnActive === index ? "active2" : ""}

이제 잘 된다 😂


사소하지만 정말 많은 고민을 안겨 주었곤 오류였다. 무심코 코딩을하다보면 생각보다 자주 만나게 되는 오류인 것 같다. 이렇게 고민하여 짚고 넘어가니 마음이 편안하다. 이런 작은 노하우가 하나하나 쌓여 실력자가 되리라..
profile
최선이 반복되면 최고가 된다.

0개의 댓글