MBTI 기반 Cake-project Question 컴포넌트를 구현한 후에 테스트를 진행하다 버그를 발견해버린다.
p요소
를 클릭해도 handleAnswerSelection
함수가 실행되어 첫번째 li 요소가 클릭되고 다음 question으로 넘어가버리는 것이였다..^_^
p요소인 문제 질문 부분을 클릭해도 첫번째 li 요소의 핸들러 함수가 실행된다.
<div>
<p>{currentQuestion.question}</p>
<ul>
{currentQuestion.options.map((option) => (
<li key={option}>
<button onClick={() => handleAnswerSelection(option)}>{option}</button>
</li>
))}
</ul>
</div>
p요소와 관련된 이벤트 핸들러도 없고, 이벤트 핸들러가 있는 요소의 부모 요소인 ul요소와도 형제 관계로 있는데 왜 ... 클릭되지..? 🤔
이벤트 버블링과 관련이 있을까?
상위 div요소로 전달된 이벤트가 p 요소에 영향을 주는것일까..?
아니면 무슨 문제일까?
우선은 p 요소에 e.stopPropagation()
메소드를 연결해서 1차적인 문제 해결을 막기는 하였다. 그런데 정확한 원인을 몰라서 답답하다.
p 요소에 클릭이벤트 제거 후 진행
👉 2번에 대한 결과 자체는 너무나도 이해가 된다.
p요소에서 클릭 이벤트가 발생되었으니 버블링이 일어나 부모인 div에 이벤트 전파가 되었고, p요소 자체만 클릭된 것으로 콘솔창을 통해 확인했다.
그런데, 왜 p요소에 이벤트를 제거하면 1번과 같은 결과가 나오는걸까?
내가 찾은 답은?
.
.
.
아마 이 글을 읽고 계신분들이라면 '뮤진 바보다~' 라는 생각을 하셨을것 같다.
나도 답을 찾고 어이가 없었기 때문에 ㅎ ㅎ ㅎ
답은 위 실험 내용에 다 나와있었다.
1. 애초에 p 요소는 버튼도 아니고 클릭이벤트도 없다.
2. li 요소 내 버튼을 클릭하면 호출되는 클릭이벤트 함수(핸들러함수)는 이벤트 버블링에 의해 부모 요소인 div까지 전달된다.
3. 버튼 근처를 클릭하면 클릭 이벤트가 버튼 상위 요소까지 전파된다.
-> 버튼 외부를 클릭했음에도 버튼의 클릭이벤트 핸들러가 실행되었던 것.. ^_^
역시 안보일 때는 잠시 쉬어야한다고~
다른 공부를 하다가 다시 문제를 들여다보니 바로 찾을 수 있었다 🥹
어쩐지 관련해서 구글링을 해보니까 뭐가 안나오더라.
버튼의 주변을 클릭했을 때 이벤트 핸들러가 실행되지 않도록 처리하려고 했다.
1. 이벤트 버블링도 막기위해 stopPropagation 메서드도 사용해보고,
2. 이벤트의 target과 current target을 비교해서 다르다면 return 해버리는 조건문도 추가해봤지만 문제가 해결되지 않았다.
그런데 또 한가지 이상한 점은..
개발자 모드를 모바일 화면 크기로 해서 실험을 하고 있었는데
2번 방법으로 시도할 경우
웹 화면 크기에서는 👉 내 의도대로 동작을 하고
모바일 화면 크기에서는 👉 내 의도대로 동작하지 않음을 확인하였다.
디바이스가 모드가 달라져 터치의 범위나 민감도가 다른가 싶었다.
하지만~
p 요소에 클릭 이벤트 핸들러를 달아주니
디바이스 모드를 모바일로 설정하여 테스트를 진행해도 내 의도대로 동작하였다..
다시 의문의 구렁텅이에 빠져버렸다..
이후에 스타일을 적용하면 당연히 요소들간의 간격이 생기기때문에
엉뚱한 곳을 클릭한다해서 버튼이 눌릴 것 같진 않지만,
오로지 버튼을 클릭했을때만 해당 버튼이 눌리게 만들고 싶다...!..🤔
위의 결과를 생각해보았을 때는 이벤트보다는 CSS와 관련 있어 보였다.
CSS로 돌아가 처음부터 생각을 해보았다.
우선 button요소는 기본적으로 block-level element
이다.
따라서 전체 가로 너비를 차지한다.
그렇기때문에 버튼의 클릭 가능한 영역이 넓을 것이다...!
그렇다면 이 영역을 줄여보자!
display 속성을 inline-block
으로 변경해주었다.
inline은 가로 너비가 내용물에 따라 조절되는 특징이 있기 때문에 자유롭게 스타일링을 하기위해 inline-block으로 변경하였고,
이제 클릭가능한 영역이 버튼 크기에 맞게 줄었을 것이다.
드디어 해결이 되어버렸다 🎉🥹🎉🥹🎉
이제 어떤 디바이스 모드에도 영향 받지 않고 버튼 내용물을 클릭해야만
온클릭 이벤트가 발생한다 !
결국은 display: inline-block
단 한줄로 해결될 문제가 돌고 돌아 해결되었다.
이벤트 버블링 때문인지 처음 의심 했을때부터 지금까지 이렇게 저렇게 시도하며 느낀 것은
정말 기초가 탄탄해야겠구나 싶었다.
동료들 + 개발을 먼저하신 분들이 공통적으로 하는 말씀을 들어보면
'기초가 가장 중요하다, 기초를 튼튼히 하자' 라는 말이 정말 많았는데
그 동안에는 별다른 이슈가 없었어서 크게 느끼지 못하다가
오늘에서야 크게 체감을 했다.
사실 나는 CSS가 가장 어렵게 느껴진다.
스타일링 할때 아래 문장들을 가장 많이 사용하는 것 같다 ㅎ
'어..? 왜.. 이게 되지?'
'어? 이게 왜 안되지?
그만큼 기초가 탄탄하지 못하다는 것이겠지.
이번 삽질을 통해 기초의 중요성과,, 이벤트에 대해 정리해볼 수 있는 귀한 삽질이었다.