본문 바로가기
WEB/JS

[javascript] pc와 모바일을 구분하고 싶을 때

by jackWillow 2020. 2. 12.

이 글은 enter key가 pc에서는 send로 모바일에서는 줄바꿈으로 동작하는 방법을 찾으며 공부한 것을 정리한 글입니다.

 

***

결론, 모바일인지 확인하려면

navigator.userAgent에서 test() 혹은 indexOf()메소드를 사용해서 실마리를 찾자

 

혹은, 키보드 이벤트라면

navigator.maxTouchPoints와 window.innerHeight를 같이쓰는것도 가능할것 같다.

***

(예시는 아래에 있습니다.)

 

pc와 모바일에서 모두 사용가능한 채팅 웹앱을 만들면서 enter key의 용도가 pc와 모바일에서 다르다는 문제를 발견했습니다. pc에서는 일반 키보드를 사용하기 때문에 enter가 send여야 편하고, 모바일에서는 가상 키보드를 사용하기 때문에 enter(return)가 줄바꿈이어야 편하기 때문입니다.

하지만, 변수가 처음 생각했던 것만큼 단순하지 않았습니다. 일반적인 pc와 모바일만 있는것이아니라, 터치 가능한 pc도 있고 버튼이 있는 모바일, 키보드를 연결한 모바일 그리고 테블릿도 있었습니다. 가장 좋은 방법은 enter 이벤트가 일반 키보드에서 온것인지 가상 키보드에서 온 것인지 구분하는 것이지만, 그 방법은 찾을 수 없었습니다.

 

그래서 다른 방법을 찾다가 3가지 불완전한 방법을 찾게 되었습니다.

바로 navigator.userAgent와 navigator.maxTouchPoints, window.devicePixelRatio 입니다.

 

1. navigator.userAgent

navigator.userAgent는 사용자 에이전트의 응용프로그램, 운영 체제, 공급업체 및 버전을 식별할 수 있도록 하는 문자열입니다.

자바스크립트로 navigator.userAgent를 통해 확인하거나 HTTP Headers에 Request Headers > user-agent에서 확인 할 수 있습니다.

User agent

그래서 userAgent을 분석해 Mobile이나 Android, iPhone 등의 문자열을 포함하고 있다면 이것이 모바일 임을 알 수 있습니다. (가장 많은 모바일 기기를 포함하는 문자열은 'Mobi, mobi' 입니다.)

 

단점은, 문자열을 탐색하는 루프문을 돌려야 합니다. 그리고 제가 찾아본 바로는 아직 모바일을 명시하는 정해진 규칙이 없습니다(2020-02-24). 그래서 Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|Mobi|mobi 등 다양한 문자들을 탐색해야하고 새로운 모바일이 탄생할때마다 추가해줘야 합니다. 그리고 희박한 확률이지만 모바일이 아님에도 불구하고 모바일 관련 문자가 포함되어 있을 수도 있습니다.

 

사용예시 : 

isMobile() {
	return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|Mobi|mobi/i.test(navigator.userAgent);
}

 

2. navigator.maxTouchPoints

navigator.maxTouchPoints 최대 동시 터치 점의 수를 반환합니다. 그러므로 터치가 가능한 기기라면 1 이상의 값을 반환하게 됩니다. 그래서 모바일 기기라면 대부분 터치가 가능하기 때문에 이것으로 구분할 있습니다.

 

하지만, 아직 확인해보지는 않았지만 예상되는 단점이 있습니다. navigator.maxTouchPoints는 단순히 터치 수를 반환하기 때문에 아마 터치가 가능한 노트북에서도 1 이상의 값을 반환할 것 같습니다.

 

그래도 키보드를 사용하는 이벤트라면 사용할 방법이 있습니다.

바로 window.innerHeight 함께 쓰는 것입니다. 모바일의 경우 text값을 입력할때 모바일 키보드가 올라오게 되는데 이때 window.innerHeight 값이 줄어들게 됩니다. 그래서 웹페이지를 로드하거나 혹은 키보드를 누르지 않았을 때의window.innerHeight값을 변수에 선언해두고 키보드를 입력했을 때의 window.innerHeight값과 비교하는 로직을 같이 쓴다면, 터치가능한 노트북의 경우를 피할 있을 것입니다.

 

사용예시(단독) : 

isMobile() {
	return navigator.maxTouchPoints;
}

 

사용예시(+ window.innerHeight)

let defaultInnerHeight = window.innerHeight;
isMobile() {
	return navigator.maxTouchPoints && window.innerHeight !== defaultInnerHeight;
}

 

3. window.devicePixelRatio

모바일 기기들은 pc 다르게 작은 화면에 많은 배율의 픽셀을 담고 있습니다. 그래서 window.devicePixelRatio 이용해서 사용자 디바이스의 픽셀 레티오를 구해 모바일 기기를 구분할 있습니다.

 

다만, 치명적인 단점이 있습니다.

바로 수는 적지만 모바일 기기 중에 window.devicePixelRatio 1 기기도 있다는 것입니다. 그래서 이 방법은 추천하지 않습니다.

 

사용예시 : 

isMobile() {
	return window.devicePixelRatio > 1;
}

 


셋다 완벽한 방법은 아니지만 그 중 가장 많이 사용하는 방법은 1. navigator.userAgent 인것 같습니다.

반응형

'WEB > JS' 카테고리의 다른 글

(js)만 나이 계산  (0) 2021.11.05
(js) class 상속 연습  (0) 2021.08.22
(js) prototype 상속 연습  (0) 2021.08.22
(js)조건절에 boolean 대신 쓸 수 있는 값  (0) 2020.10.10
keyCode 229가 뜰 때  (12) 2020.02.05