- 프로젝트: vegimap, tracking map
- 키워드: safari, iPhone, navigation gestures, date constructor, cross browsing
- 상황 1
- vegimap은 지도가 화면 전체를 차지하고 있다.
- iphone에서 touch gesture로 지도를 이동하다보면 navigation gesture가 작동하여 페이지가 이전/이후로 이동해버릴 때가 있다.
- 지도 타일을 터치할 때는 navigation gesture가 작동하지 않도록 하고자 한다.
- 해결방법 1
- 특정 DOM element를 touch했을 때, navigation gesture가 실행되지 않도록 하는 custom hook을 작성한다.
// useBlockNavigationGesture.ts import { useEffect } from 'react'; const useBlockNavigationGesture = (elementId: string): null => { function blockNavigationGesture(e: TouchEvent) { const { target } = e.touches[0]; if ((target as HTMLElement).tagName !== 'IMG' || (target as HTMLImageElement).src?.includes('markers')) return; const { clientX } = e.touches[0]; if (clientX > 50 && clientX < window.innerWidth - 50) return; e.preventDefault(); } useEffect(() => { const mainElement = document.getElementById(elementId); mainElement?.addEventListener('touchstart', blockNavigationGesture); return () => { mainElement?.removeEventListener('touchstart', blockNavigationGesture); }; }, [elementId]); return null; }; export default useBlockNavigationGesture;
먼저 naver map tile은 IMG 태그이고, Marker image에 대해서는 touch가 정상적으로 이루어져야하기 때문에, tagName이 IMG가 아니거나, 마커인 경우에는 바로 return 한다.
그 후 touch한 부분의 clientX 값이 화면의 왼쪽(< 50)이나 오른쪽(> window.innerWidth - 50)이면, 'e.preventDefault()'를 실행하여 navigation gesture의 실행을 막는다.
preventDefault() 메서드는 어떤 이벤트를 명시적으로 처리하지 않은 경우, 해당 이벤트에 대한 사용자 에이전트의 기본 동작을 실행하지 않도록 지정합니다. - custom hook을 NAVER MAP element에 적용한다.
// MapSection.tsx useBlockNavigationGesture(mapSectionId); return ( <> <MapSection id={mapSectionId}> <NaverMap {...} /> ... </MapSection> ... </> );
- naver map tile에 대해서는 navigation gesture 없이 map move gesture만 작동하고, marker click 이벤트는 기존과 똑같이 동작하는 것을 확인했다!
- 특정 DOM element를 touch했을 때, navigation gesture가 실행되지 않도록 하는 custom hook을 작성한다.
- 상황 2
- Date를 생성하고 두 date의 시간 차이를 구하는 로직이 있다.
const startTime = new Date('2022-04-09 06:00:00'); const endTime = new Date('2022-04-09 23:59:59'); endTime.getTime() - startTime.getTime()
- 크롬에서는 잘 작동하지만 safari에서는 정상적으로 작동하지 않는다.
- Date를 생성하고 두 date의 시간 차이를 구하는 로직이 있다.
- 해결 방법 2
- safari는 특정 형식의 string consturctor를 제대로 parsing하지 못한다는 것을 알게 되었다.
- dayjs 등의 라이브러리를 써도 되지만, 간단한 로직이기 때문에 js에서 지원하는 공식적인 constructor 형식을 사용하기로 한다.
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Date#several_ways_to_create_a_date_object
const startTime = new Date(2022, 3, 9, 6, 0, 0); // 월은 0부터 시작 const endTime = new Date(2022, 3, 9, 23, 59, 59); // 월은 0부터 시작
- 이제 사파리에서도 정상적으로 Date 객체가 생성된다!
- safari는 특정 형식의 string consturctor를 제대로 parsing하지 못한다는 것을 알게 되었다.
'프론트엔드' 카테고리의 다른 글
JENNIFER Front로 웹사이트 모니터링하기 (0) | 2022.05.22 |
---|---|
package.json에서 yarn resolutions 적용하기 (0) | 2022.05.21 |
Web Worker로 setTimeout을 백그라운드에서 유지하기 (0) | 2022.04.20 |
Hammer.js로 swipe 이벤트 감지하기 (0) | 2022.04.02 |
모바일 기기에서 scroll 관련 버그 대응하기 (0) | 2022.04.02 |