이전 포스트에서 모바일에서의 클릭 이벤트로 인해 6가지 이벤트가 연쇄적으로 발생하는 것을 발견했습니다.
touchstart → touchend → mousemove → mousedown → mouseup → click
이번에는 다양한 상황에서의 클릭 이벤트의 시퀸스를 테스트해보고 정리해보겠습니다.
또한, 여러가지 상황에 따른 이벤트 시퀸스가 다른 이유에 대해서도 탐구해보겠습니다.
먼저, 모바일과 데스크톱 상황에서의 클릭 이벤트는 서로 다르게 적용됩니다.
데스크톱은 마우스를 움직이는 도중에 특정 시점에서의 클릭으로 이벤트가 발생하지만, 모바일에서는 마우스는 존재하지 않고 특정 시점의 유저 손가락 터치로 이벤트가 발생하기 때문입니다.
따라서, 먼저 데스크톱 상황에서 발생하는 이벤트에 대해 살펴보겠습니다.
실험 방법
- 크롬 브라우저를 토대로 실험하였습니다.
- 클릭 이벤트와 관련된 이벤트를 body 에 eventListener 를 등록한 이후, 이벤트 발생시 로그를 찍도록 만들었습니다.
useEffect(() => {
;['touchstart', 'touchmove', 'touchend', 'mousedown', 'mousemove', 'mouseup', 'click', 'contextmenu'].forEach(eventType => {
document.addEventListener(eventType, event => {
console.log(`Event detected: ${eventType}`)
console.log(`Event target:`, event.target)
})
})
}, [])
데스크톱 클릭 이벤트
데스크톱에서의 클릭 이벤트는 간단합니다.
마우스 클릭시 mousedown → mouseup → click 순으로 이벤트가 발생합니다.
모바일 클릭 이벤트
모바일에서의 클릭 시퀸스가 다양했습니다.
4가지 모바일 터치 이벤트 발생 상황에서의 이벤트 시퀸스는 다음과 같습니다.
모바일 환경 테스트를 위해서는 개발자 도구의 반응형 페이지를 관찰하는 “Toogle Device Toolbar” 기능으로 진행하였습니다.
1. 일반적인 터치
터치를 한 후에 마우스(손)을 이동하지 않고 빠른 시간 내에 원래 자리에서 떼는 경우입니다.
[1편] 에서 보았듯이, 6가지 이벤트 시퀸스가 연속적으로 발생하고 있습니다
- touchstart > touchend > mousemove > mousedown > mouseup > click
2. 일반적인 터치 + 시간이 지난 후에 떼기
일반적인 터치 실험과 마찬가지로 제자리에서 누르고 떼는 동작을 실행하지만, 일정 시간이 지난 후에 떼는 경우입니다.
- touchstart > mousemove > contextmenu
특이하게도, 해당 경우 contextmenu 이벤트가 발생합니다.
이를 “long press” 라고 하며, 여러분은 이미 모바일에서 수 없이 많이 사용하고 있습니다.
예를 들어, 앱 아이콘을 꾹 눌러서 위치를 바꾼 경험이 있지 않으신가요?
바로 이러한 상황이 long press가 작동되고 있던 상황입니다.
Q. 일반 Touch와 Long Press를 구분하는 시간적 간격이 존재할 것 같은데요. 몇 초 인가요?
운영체제 마다 다르다고 합니다. 기본적으로 300 ~ 500ms 이지만, 변동의 여지가 있으며 핸드폰 사용자마다 이를 다르게 설정할 수 있는 기능이 있어, 확정할 수 없습니다.
3. 터치 후 이동
일반적인 터치 이후 옆으로 이동했을 때 발생하는 이벤트입니다.
중간의 touchmove 이벤트는 커서가 이동할 때 계속 발생합니다. (아래 예시는 한번만 나오도록 찍은 것)
- touchstart > touchmove > touchend
4. 두 손가락 터치
두 손가락 터치는 안드로이드의 유선 디버깅 환경에서 테스트하였습니다.
다음과 같은 시퀸스로 이벤트가 발생했습니다.
- touchstart > touchstart > touchend > touchend
두 손가락 터치는 pinch-zoom(두손가락으로 확대,축소) 기능을 사용하기 위한 초기 단계로 이해하시면 되겠습니다.
💡 Pinch-Zoom에 대한 자세한 공부는 더 해봐야겠습니다.
이렇게 이벤트 시퀸스가 다른 이유는 무엇일까요?
앞서 살펴보았듯이, 모바일과 데스크톱 환경에서의 클릭(터치)는 매우 다른 성격을 지니고 있습니다.
모바일 환경에서의 클릭은 Context 메뉴를 여는 long-press, 확대/축소를 하는 Pinch-Zoom 등 다양한 상황으로의 전환 가능성이 있습니다.
따라서, 이벤트 중간에 시간적 간격을 두어 다양한 상황이 발생할 수 있는 시간적 임계치를 설정한 것입니다.
이러한 임계치는 브라우저마다 · 운영체제마다 다르다고 합니다.
현업에서 어떻게 모든 상황에 대처하는지 궁금해지네요. 아시는 분은 댓글로 남겨주시면 감사하겠습니다.
다음 편에는 학습한 지식을 토대로 제가 제작했던 외부 클릭 커스텀 훅을 제작했던 과정을 소개해드리겠습니다.
'웹 프로그래밍 > React' 카테고리의 다른 글
NPM 패키지 개발 1편 [타 라이브러리 사용 트러블 슈팅 과정] (0) | 2025.01.09 |
---|---|
[Tanstack Query] setMutationDefaults로 key 모듈화하여 관리하기 (0) | 2024.12.12 |
[Tanstack Query] queryFc의 인자 FunctionContext에 대해 알아보자 (1) | 2024.11.26 |
[React] 제어 컴포넌트 vs 비제어 컴포넌트 (0) | 2024.07.29 |
[Zustand] 상태관리 방법 및 Little Bit Deep Dive (0) | 2024.07.22 |