codestates / codestates/art-ground

[Error Handling Log] IOS 모바일 기기에서 mouse- event가 작동하지 않는 문제점 해결하기 / 박지영

Open
#318 0 comments 0 reactions 1 assignee Claimed by @devLuenna View on GitHub
Error Handling Log
Dominant language
JavaScript
Stars
7
Forks
9
PR merge metrics
No merged PRs in 30d

Description

### 에러사항

- 이미지 slider를 구현하는데 pc버전에서는 그냥 버튼으로 이미지 이동시키면 되지만, 모바일 버전에서는 터치가 필요할 때도 생김.
- 에러사항: PC 페이지에서는 이벤트 들이 제대로 실행 되었는데, 모바일에서는 실행되지 않았다.

### 에러 해결 방법

- 일단, 모바일에서는 이벤트의 종류가 PC 버전과는 상이하다(대표적으로는 touch, click, mouse 세 가지가 헷갈림)
- mouse : 컴퓨터와 연결된 mouse와 관련된 이벤트. 마우스의 up, down, move, whell 들이 있다.
- click : touch up & down, mouse up & down 을 묶은 이벤트
- touch : display를 touch 했을 때 일어나는 up, down, move 등의 이벤트가 있다
- 즉 mouse 이벤트는 touch 이벤트에 연결이 되지 않는다! ***(중요)

- mouse-/ touch- 이벤트 비교:
- onMouseDown, onMouseUp: 모바일에서 사용 불가
- onTouchStart, onTouchEnd: PC에서는 사용 불가. PC에서 사용하는 onMouseDown, onMouseUp 이벤트의 모바일 버전. 이벤트 기능은 동일하다.

- 따라서, 기존의 click 이벤트를 touch 이벤트로 변경했다.
- 어차피 웹에서는 좌/우 버튼이나 9개 땡땡이 버튼으로 슬라이더를 작동하기 때문에 마우스 클릭하면서 드래그 하는 이벤트는 필요없다.
- 우선 `onTouchStart`로 화면에 터치되는 순간의 x좌표와 상태값으로 저장해야하는데, 이벤트 객체에서 좌표값을 접근하는 방식에 차이가 있었음.
- 클릭이벤트 시 X좌표: `e.pageX`
- 터치 이벤트 시 X좌표: `e.changedTouches[0].pageX`
- `onTouchEnd`는 화면에서 손을 뗄 때 발생하는 이벤트. 터치할 때 저장한 상태값과 손을 뗄 때 좌표값을 비교해서 총 이동거리가 100보다 큰 경우에 슬라이더가 움직이게 했다.
- (참고) 아래 코드에선 사용하진 않았지만, `onMouseMove` 이벤트의 모바일 버전은 `onTouchMove`이다.

```jsx
const [mouseDownClientX, setMouseDownClientX] = useState(0);
const [mouseUpClientX, setMouseUpClientX] = useState(0);
//const [cursorOn, setCursorOn] = useState(false);

const onMouseDown = (e) => {
e.preventDefault();
setMouseDownClientX(e.pageX);
//setCursorOn(true);
};
const onMouseUp = (e) => {
setMouseUpClientX(e.pageX);
//setCursorOn(false);
};

useEffect(() => {
const dragSpace = Math.abs(mouseDownClientX - mouseUpClientX); //두 좌표의 차이의 절대값
if (mouseDownClientX !== 0) {
if (mouseUpClientX < mouseDownClientX && dragSpace > 100) {
sliderUp();
} else if (mouseUpClientX > mouseDownClientX && dragSpace > 100) {
sliderDown();
}
}
}, [mouseUpClientX]);

return(



// ...




)

//변경 후 코드
const [mouseDownClientX, setMouseDownClientX] = useState(0);
const [mouseUpClientX, setMouseUpClientX] = useState(0);

const onMouseDown = (e) => {
setMouseDownClientX(e.changedTouches[0].pageX);
};
const onMouseUp = (e) => {
setMouseUpClientX(e.changedTouches[0].pageX);
};

useEffect(() => {
const dragSpace = Math.abs(mouseDownClientX - mouseUpClientX); //두 좌표의 차이의 절대값
if (mouseDownClientX !== 0) {
if (mouseUpClientX < mouseDownClientX && dragSpace > 100) {
sliderUp();
} else if (mouseUpClientX > mouseDownClientX && dragSpace > 100) {
sliderDown();
}
}
}, [mouseUpClientX]);

return(


// ...




)
```

- 웹에서 click이벤트가 pc에선 문제 없지만, IOS 모바일 기기에서 확인해보면 약간 반응이 느린 이유?
- IOS가 의도적으로 클릭이벤트를 지연시키기 때문
- 일부러 클릭이벤트를 지연시켜 제스쳐/스와이프가 올바르게 작동하게 하기 위함
- 이를 해결하기 위해선 touchStart, touchend 등의 이벤트를 사용해야 함(두 이벤트는 click 이벤트와 달리 300ms의 지연 없이 즉시 실행)
- 하지만 click 이벤트도 넣어야하고 touch이벤트도 넣어야할 때는? 이런식으로 하면 touch이벤트가 있는 브라우저면 touch 아니면 click이 반환된다.

```jsx
var clickEvent = (function() {
if ('ontouchstart' in document.documentElement === true) {
return 'touchstart';
} else {
return 'click';
}
})();

target.addEventListener(clickEvent,function(){
// ...
});
```

- 모바일에서의 click/ mouse-/ touh- 이벤트
- event 발생 순서:
- 1. Touch-2. Mouse-3. Click
- 이벤트 간에는 간섭이 없다.
- 멈춤이 필요한 경우 원하는 이벤트 순서에 e.preventDefault() 호출
- Touch event는 multi-touch 가 가능하다.
- Zoom-in/out 시에도 동작하여 불필요한 로그 호출
- Touch event는 스크롤 시에도 발생한다.
- 딜리스트를 스크롤할 경우 불필요 로그 매번 호출
- iPhone X/safari 테스트 시 touch 이벤트는 즉시, mousedown/up 이벤트는 click과 묶어서(배치)처럼 화면에 표현

<아래 내용은 추가로 뜯어봐야 함>

- 특히 고려해야할 부분은 3-zoom-in-out / 4-scroll 이므로 touch보다는 mousedown, click 으로 사용하여야 합니다.
- 둘중에 Click이 아니라 mousedown을 사용하였을때 좋은 점은 모바일에서 터치에 대한 딜레이가 있기 때문인 것 같습니다.

- 참고한 링크:

[https://velog.io/@awesomelon/IOS-모바일-기기에서-click-event-사용시-문제점JS](https://velog.io/@awesomelon/IOS-%EB%AA%A8%EB%B0%94%EC%9D%BC-%EA%B8%B0%EA%B8%B0%EC%97%90%EC%84%9C-click-event-%EC%82%AC%EC%9A%A9%EC%8B%9C-%EB%AC%B8%EC%A0%9C%EC%A0%90JS)

[https://medium.com/@rnrjsah789/모바일에서의-click-mouse-touch-event-bfa74f6b2ce3](https://medium.com/@rnrjsah789/%EB%AA%A8%EB%B0%94%EC%9D%BC%EC%97%90%EC%84%9C%EC%9D%98-click-mouse-touch-event-bfa74f6b2ce3)

[https://kimgoingto.tistory.com/5](https://kimgoingto.tistory.com/5)

[https://velog.io/@hemtory/ReactTouchEvent](https://velog.io/@hemtory/ReactTouchEvent)

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.