이전에 노션에 정리를 해둔 내용이나, 제대로 정리되지 않은 부분이 있어 블로깅을 하게 되었다. 그리고 노션은 나만 보기도 하니깐!
문제상황
나는 아이콘에 mouse를 hover했을 때 dropdown 메뉴가 화면에 노출되고, 메뉴 안에 있는 값을 클릭했을 때 해당 값이 선택되도록 구현하고 싶었다.
dropdown 메뉴를 구현하기 위해 <div>에게 onMouseOver 이벤트와 onMouseOut 이벤트를 등록한 상황이다.
근데 여기서 확인되는 첫 번째 문제점이 있었다.
선택된 영역 위에, 즉 div 위에 마우스를 올렸을 때 onMouseOver 이벤트만 발생되어야 하는데, onMouseOut 이벤트도 발생되는 문제점이 있었다.
참고로 onMouseOut 이벤트는 마우스의 커서가 해당 요소에서 위치하다가 빠져나갈 때 일어나는 이벤트이고, onMouseOver 이벤트는 마우스의 커서가 해당 요소 위에 위치할 때 일어나는 이벤트이다.
간단하게 코드로 보자면 아래와 같다.
<div
onMouseOver={() => {
console.log('mouseOver');
setIsHover(true);
}}
onMouseOut={(e: any) => {
console.log('Mouse out the element');
setIsHover(false);
}}
className="border-2"
>
<Icons icon={faUser} onClick={moveToMyPage} />
{isHover && <IsHover />}
</div>;
까만색 border는 div 영역이고, 초록색 border는 Icons 컴포넌트 영역이다.
초록색 border 안에서만 마우스를 이동했을 때, onMouseOver 이벤트만 실행되어야 한다. 하지만 Mouse out the element도 출력되는 것을 확인할 수 있다. (초록색 border를 안을 제외한 까만색 border 안쪽에서 마우스를 이동했을 때는 onMouseOver 이벤트만 실행된다.)
해결 과정
일반적으로 onMouseOver 이벤트는 마우스 포인터가 요소 위로 이동할 때 발생하고, onMouseOut 이벤트는 마우스 포인터가 요소를 벗어날 때 발생한다.
그러나, onMouseOver 이벤트가 발생하는 영역이 다른 영역을 포함하고 있는 경우, 마우스 포인터가 이벤트 대상 요소를 벗어나 다른 영역 위로 이동할 때 onMouseOut 이벤트가 발생할 수 있다.
위의 코드로 설명하자면 div 요소에 onMouseOver 이벤트와 onMouseOut 이벤트를 설정하고, 이 요소가 Icons 컴포넌트를 포함하고 있는 경우, 마우스 포인터가 Icons 컴포넌트 위로 이동할 때 onMouseOut 이벤트가 발생할 수 있는 것이다.
이를 방지하려면, onMouseOut 이벤트 핸들러에서 이벤트 대상 요소가 이벤트가 발생한 요소의 자식 요소인지 확인하여, 자식 요소 위로 마우스 포인터가 이동한 경우 이벤트를 무시하도록 처리해주면 된다.
<div
onMouseOver={() => {
console.log('mouseOver');
setIsHover(true);
}}
onMouseOut={(e) => {
if (!e.currentTarget.contains(e.relatedTarget)) {
console.log('Mouse out the element');
setIsHover(false);
}
}}
className="border-2"
>
<Icons icon={faUser} onClick={moveToMyPage} />
{isHover && <IsHover />}
</div>;
onMouseOut 이벤트 핸들러에서 contains() 메서드를 사용하여, 이벤트 대상 요소가 이벤트가 발생한 요소의 자식 요소인지를 확인했다. 이를 통해, 자식 요소 위로 마우스 포인터가 이동한 경우에만 이벤트를 무시할 수 있도록 처리해줬다.
그럼 아까와 똑같은 상황으로 실험을 했을 때 아래와 콘솔 출력 결과를 확인할 수 있다.
질문이나 잘못된 점은 댓글로 남겨주세요 :)💖
'프로젝트' 카테고리의 다른 글
이미지와 데이터 서버로 같이 전송하는 법 - FormData 생성 및 사용법 (0) | 2023.08.12 |
---|---|
이벤트 버블링이 되지 않았던 문제 해결하기 (0) | 2023.03.26 |
[React] 메모리에 있는 값과 화면에 보여지는 값이 상이한 문제 (0) | 2023.03.08 |
댓글