회사에서 콘텐츠 작업을 하던 중, 사용자가 웹에서 접근하는건지, 태블릿으로 접근하는건지 구분해야하는 로직이 필요했다. 그래서 사용자들이 접속하는 기기에 따라 로직을 분리하고자 기기유형을 판별하는 법을 찾아보게 되었다.
크게 총 3가지가 존재한다.
사용자의 브라우저가 서버에 전송하는 user-agent 헤더를 검사하여 어떤 종류의 기기를 사용하는지 추측할 수 있다. (사용자가 직접 조작해 변경할 수 있으므로 정확도는 낮음)
user-agent란?
User-Agent는 웹 브라우저나 다른 클라이언트가 웹 서버에 요청을 보낼 때 자신의 정보를 서버에 전달하는 문자열. 이 문자열은 클라이언트의 종류, 버전, 운영체제, 렌더링 엔진, 디바이스 등의 정보를 포함하고 있다.
user-agent 문자열을 분석한다. (정규표현식 사용)
ex) 특정 키워드나 패턴을 검색하여 기기를 식별할 수 있다.
const userAgent = navigator.userAgent;
// 태블릿이나 모바일 기기인지 확인
if (/(tablet|ipad|playbook|silk)|(android(?!.*mobile))/i.test(userAgent)) {
console.log("This is a tablet.");
} else if (/Mobile/i.test(userAgent)) {
console.log("This is a mobile device.");
} else {
console.log("This is a desktop or laptop.");
}
태블릿, PC 그리고 모바일은 일반적으로 다른 해상도를 가지고 있다. 창의 너비와 높이를 통해 기기 유형을 추정할 수 있다. (반응형 개발할 때, css의 조건을 거는 방식과 동일하다)
외부 라이브러리를 이용해 기기 유형을 식별 할 수 있다. (거의 다 JS에서 제공해주는 기본 user-agent 기능 이용)
ex) UAParser.js, MobileDetect.js, Detect.js ...등
ontouchstart
이벤트는 터치 장치에서 발생하는 이벤트로, 이를 통해 터치 가능한 장치(스마트폰, 태블릿 등)를 감지할 수 있다.
사용자의 장치가 터치스크린을 지원하는지 확인하는 간단한 방식이다!
const isTouchDevice = "ontouchstart" in window;
//isTouchDevice가 true이면 터치스크린 지원 기기
//isTouchDevice가 false면 터치스크린이 없는 데스크톱 장치
-> 난 1번과 4번 방식을 번갈아가며 사용했다!
1번 방식을 이용해 기기들을 분리하던 중, iOS를 구분하던 중 오류가 발생했다.
iOS의 같은 경우 보통 아래와 같은 로직으로 판단한다.
const isIOS = navigator.userAgent.match(/iPhone|iPad|iPod/i) === null ? false : true;
iOS 디바이스의 브라우저나 애플리케이션의 웹뷰에서는 "iPhone" 이나 "iPad" 등이 포함되어 있기 때문에 위와 같이 판단할 수 있었다!
하지만, iOS 버전이 업데이트 되면서(iOS 13이상) iPad의 user-agent 값이 Mac과 동일하게 아래와 같이 바뀌었다!
그래서 iPad의 경우 isIOS가 계속 false가 나오는 것이다!!!
그래서 새로운 방식 중 하나인navigator.maxTouchPointsnavigator
를 이용해 구분하기로 했다.
navigator.maxTouchPointsnavigator 란?
터치 포인트(Touch Points)의 개수를 감지할 수 있는 속성으로 터치스크린 장치에서 동시에 인식할 수 있는 터치 지점의 수를 반환한다!
이게 값이 기기 별로 다른 숫자가 나온다. (iPad이냐 갤럭시 패드이냐에 따라 다르게 나온다!)
navigator.maxTouchPointsnavigator 속성 중 디바이스의 최대 동시 터치 수를 return 하는 속성이 있고, iPad의 경우 5를 return한다!
/** 태블릿 판단 */
const userAgent = navigator.userAgent;
if (
/(tablet|ipad|playbook|silk)|(android(?!.*mobile))/i.test(userAgent) ||
/Mobile/i.test(userAgent) ||
navigator.maxTouchPoints == 5 || // 아이패드 일 때 확인
navigator.maxTouchPoints == 1
) {
그래서 나는 추가적으로 touchPoints 까지 조건을 걸어 패드를 구분할 수 있었다!
참고자료 : iOS 13 iPad의 User-agent 이슈