JavaScript를 사용하여 '터치 스크린'장치를 감지하는 가장 좋은 방법은 무엇입니까?


416

데스크톱 및 모바일 장치 모두에서 사용할 수있는 jQuery 플러그인을 작성했습니다. 장치에 터치 스크린 기능이 있는지 감지하는 JavaScript가 가능한지 궁금했습니다. jquery-mobile.js를 사용하여 터치 스크린 이벤트를 감지하고 iOS, Android 등에서 작동하지만 사용자의 장치에 터치 스크린이 있는지 여부에 따라 조건문을 작성하고 싶습니다.

가능합니까?


document.documentElement에서 var x = 'touchstart'가 더 좋습니다. CONSOLE.LOG true를 반환 // (X) // 다른 반환 거짓을 지원하는 경우
Risa__B

새로운 기술이 여전히 등장 할 때 왜이 스레드가 보호 됩니까?
Andy Hoffman

답변:


139

업데이트 : 전체 기능 탐지 라이브러리를 프로젝트로 가져 오기 전에 아래 blmstr의 답변을 읽으 십시오. 실제 터치 지원 감지는 더 복잡하며 Modernizr은 기본 사용 사례 만 다룹니다.

Modernizr 은 모든 사이트에서 모든 종류의 기능 탐지를 수행 할 수있는 훌륭하고 가벼운 방법입니다.

단순히 각 기능의 html 요소에 클래스를 추가합니다.

그런 다음 CSS 및 JS에서 이러한 기능을 쉽게 대상으로 지정할 수 있습니다. 예를 들면 다음과 같습니다.

html.touch div {
    width: 480px;
}

html.no-touch div {
    width: auto;
}

그리고 자바 스크립트 (jQuery 예제) :

$('html.touch #popup').hide();

88
Modernizr은 터치 스크린을 테스트하지 않습니다. 브라우저에 터치 이벤트가 있는지 테스트합니다. 문서의 "기타 테스트"섹션을 참조하십시오 : modernizr.com/docs/#features-misc
Harry Love

1
또한 (Modernizr.touch) {/ * touch touch /} else {/ fine, do n't * /} 인 경우 터치 이벤트가 있는지 JS 테스트를 수행 할 수 있습니다
Anatoly G

7
@harrylove의 견해에 따르면, Windows 8이 나온 이후 Modernizr은 모든 PC 브라우저를 터치 호환으로 잘못 반환했습니다.
Anton

3
업데이트 : blmstr의 대답이 더 좋으며 순수한 Javascript 솔루션입니다.
Alan Christopher Thomas

1
Modernizr.touch예기치 않게로 돌아 오는 경우 undefined터치 이벤트 감지를 지원하지 않고 사용자 정의 된 Modernizr (선택 및 선택)이있을 수 있습니다.
Henrik N

679

이 기능을 사용해 보셨습니까? (이것은 Modernizr이 사용했던 것과 동일합니다.)

function is_touch_device() {  
  try {  
    document.createEvent("TouchEvent");  
    return true;  
  } catch (e) {  
    return false;  
  }  
}

console.log(is_touch_device());

업데이트 1

document.createEvent("TouchEvent")true최신 크롬 으로 돌아 가기 시작했습니다 (17 절). Modernizr는 이것을 얼마 전에 업데이트했습니다. 여기서 Modernizr 테스트를 확인하십시오 .

다음과 같이 기능을 업데이트하여 작동 시키십시오.

function is_touch_device1() {
  return 'ontouchstart' in window;
}

console.log(is_touch_device1());

업데이트 2

위의 내용이 IE10에서 작동하지 않는 것으로 나타났습니다 (MS Surface에서 false 반환). 수정 사항은 다음과 같습니다.

function is_touch_device2() {
  return 'ontouchstart' in window        // works on most browsers 
  || 'onmsgesturechange' in window;  // works on IE10 with some false positives
};

console.log(is_touch_device2());

업데이트 3

'onmsgesturechange' in window일부 IE 데스크톱 버전에서는 true를 반환하므로 신뢰할 수 없습니다. 이것은 약간 더 안정적으로 작동합니다.

function is_touch_device3() {
  return !!('ontouchstart' in window        // works on most browsers 
  || navigator.maxTouchPoints);       // works on IE10/11 and Surface
};

console.log(is_touch_device3());

2018 업데이트

시간이 지남에 따라 이것을 테스트하는 새롭고 더 나은 방법이 있습니다. 나는 기본적으로 Modernizr의 확인 방법을 추출하고 단순화했습니다.

function is_touch_device4() {
    
    var prefixes = ' -webkit- -moz- -o- -ms- '.split(' ');
    
    var mq = function (query) {
        return window.matchMedia(query).matches;
    }

    if (('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {
        return true;
    }

    // include the 'heartz' as a way to have a non matching MQ to help terminate the join
    // https://git.io/vznFH
    var query = ['(', prefixes.join('touch-enabled),('), 'heartz', ')'].join('');
    return mq(query);
}

console.log(is_touch_device4());

여기서 그들은 비표준 touch-enabled미디어 쿼리 기능을 사용하고 있습니다. 이것은 다소 이상하고 나쁜 습관이라고 생각합니다. 그러나 이봐, 현실 세계에서 나는 그것이 작동한다고 생각한다. (그들은 모두 지원하는) 앞으로 그 미디어 쿼리 기능은 당신에게 동일한 결과를 줄 수 : pointerhover.

Modernizr이 어떻게하고 있는지 소스를 확인하십시오 .

터치 감지 문제를 설명하는 유용한 기사를 보려면 Stu Cox : 터치 스크린을 감지 할 수 없습니다를 참조하십시오 .


20
이중 탕 중 하나를 반환하는 기능 강제 부울에 값을 캐스트 true또는 false. 자세한 내용은 여기를 참조하십시오 : stackoverflow.com/questions/4686583/…
Rob Flaherty

2
Opera Mobile 10 또는 Internet Explorer Mobile 6 (Windows Mobile 6.5)에서는 작동하지 않습니다.
doubleJ

17
in연산자가 이미 부울로 평가 되므로 이중 NOT (!!)은 불필요합니다 .
Steve

11
'onmsgesturechange'비 터치 장치 (PC)에서도 마찬가지입니다. window.navigator.msMaxTouchPoints더 정확한 것 같습니다. 여기에서 찾았습니다 .
Steve

6
화면에 터치 센서가 없어도 Windows 8의 IE10에서는 true로 평가됩니다. 이전 랩톱을 Windows 7에서 Windows 8로 업그레이드했습니다.
Pwner

120

Modernizr은 Windows Phone 8 / WinRT에서 IE10을 감지하지 못하므로 간단한 크로스 브라우저 솔루션은 다음과 같습니다.

var supportsTouch = 'ontouchstart' in window || navigator.msMaxTouchPoints;

기기가 터치를 갑자기 지원하지 않거나 지원하지 않기 때문에 한 번만 확인하면되므로 여러 번 더 효율적으로 사용할 수 있도록 변수에 저장하면됩니다.


3
창의 'onmsgesturechange'는 비 터치 장치에서 "데스크톱"IE10도 감지하므로 터치를 결정하는 신뢰할 수있는 방법이 아닙니다.
매트 스토우

6
이 답변은 가장 훌륭하고 가장 단순하고 최신 답변이므로 받아 들여 져야합니다. 함수에서 나는 이것이 더 일관성이 있다고 생각합니다 : return !!('ontouchstart' in window) || !!('msmaxtouchpoints' in window.navigator);(두 답변을 결합하기 위해) IE10에서도 잘 작동합니다!
Yeti

이것이 정답입니다. 'onmsgesturechange' in window반환 터치가 가능 IE10 바탕 화면에 사실 경우에도
샘 손튼

6
필요한 것 :function isTouchDevice() { return 'ontouchstart' in window || !!(navigator.msMaxTouchPoints);}
GFoley83

1
창에서 'ontouchstart'의 GFoleys 제안조차 || !! (navigator.msMaxTouchPoints); 30 dev에 2월 2014 크롬에서 반환 FALS 긍정적
톰 앤더슨

37

위의 모든 주석을 사용하여 내 요구에 맞는 다음 코드를 작성했습니다.

var isTouch = (('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0));

나는 이것을 iPad, Android (브라우저 및 Chrome), Blackberry Playbook, iPhone 4s, Windows Phone 8, IE 10, IE 8, IE 10 (터치 스크린이있는 Windows 8), Opera, Chrome 및 Firefox에서 테스트했습니다.

현재 Windows Phone 7에서 실패하고 해당 브라우저에 대한 솔루션을 아직 찾을 수 없습니다.

누군가가 이것을 유용하게 사용하기를 바랍니다.


사용할 수없는 이유가 있습니까? function is_touch_device () {return !! ( 'ontouchstart'in window) || !! (네비게이터에서 'msmaxtouchpoints'); };
sidonaldson

함수를 사용하면 작동하지만 일반적으로 위의 변수 방법을 사용하여 한 번만 테스트하고 나중에 코드에서 확인할 때 더 빠릅니다. 또한 터치 스크린이없는 Windows 8에서 msMaxTouchPoints가 IE 10으로 0보다 큰지 여부를 테스트해야한다는 것을 알았습니다 .msMaxTouchPoints로 0을 반환했습니다.
David

true윈도우 7에서 내 Firefox 32에서 반환 : (
vsync

Windows 8의 Firefox 33 및 33.1은 모두 내 시스템에서 올바르게 표시되지 않습니다. Firefox를 최신 버전으로 업그레이드해도 여전히 true를 반환합니까? 컴퓨터에 장치가 설치되어있어 Firefox가 컴퓨터에 닿았다고 잘못 생각할 수 있습니까?
David

>>> 창에서 'ontouchstart'>>> 우분투에서 진정한 FF 51.0.1
Ravi Gadhia

25

상호 작용 미디어 기능 이 도입 되었으므로 간단히 수행 할 수 있습니다.

if(window.matchMedia("(pointer: coarse)").matches) {
    // touchscreen
}

https://www.w3.org/TR/mediaqueries-4/#descdef-media-any-pointer

업데이트 (의견으로 인해) : 위의 해결책은 "거친 포인터"(일반적으로 터치 스크린)가 기본 입력 장치인지 감지하는 것입니다. 마우스와 같은 장치에 터치 스크린이 있는지 여부를 결정하려는 경우 사용할 수 있습니다any-pointer: coarse 대신 .

자세한 내용은 여기를 참조하십시오. 브라우저에 마우스가없고 터치 전용인지 감지


3
이것은 최고의 솔루션입니다. 감사합니다! (pointer: coarse)기본 입력 만 타겟팅하는 것이 좋습니다 . 지원되지 않는 소수의 브라우저는 데스크톱 전용이므로 프로덕션 환경에서 사용할 수 있습니다. css-tricks에 대한 훌륭한 기사가 있습니다.
Fabian von Ellerts

2
이것은 모든 상황에서 작동하는 유일한 테스트 솔루션입니다. 감사!
kaiserkiwi

20

난이게 좋아:

function isTouchDevice(){
    return typeof window.ontouchstart !== 'undefined';
}

alert(isTouchDevice());

12
부울을 리턴하기 위해 3 진 표현식을 사용할 필요가 없습니다. 부울을 리턴하려면 표현식을 사용하십시오. function isTouchDevice(){ return (window.ontouchstart !== undefined); }
Tim Vermaelen

1
당신은 또한 사용할 수 있습니다 : var isTouch = 'ontouchstart' in window;, 그러나 이것은 최신 Chrome (v31)에서는 작동하지 않지만 var isTouch = 'createTouch' in window.document;여전히 작동합니다.
Olivier

2
이전에 허용 된 질문의 의견에서 이미 언급했듯이. "Modernizr은 터치 스크린을 테스트하지 않습니다. 브라우저에 터치 이벤트가 있는지 테스트합니다." 귀하의 함수는 기술적으로 isTouchEvents () is isTouchDevice () 아님
hexalys

touchstartIE는 pointer대신 이벤트를 사용하기 때문에 유사한 방법 테스트만으로 Surface를 터치 장치로 인식하지 못합니다 .
CookieMonster

1
@Nis가 옳았지만 Firefox 39에서는 false를 올바르게 반환합니다.
Dan Dascalescu 1

17

당신이 사용하는 경우 모더 나이저를 , 그것은 매우 쉽게 사용할 수 있나요 Modernizr.touch앞서 언급 한 바와 같이.

그러나 Modernizr.touch안전한 사용을 위해 조합 및 사용자 에이전트 테스트를 사용하는 것이 좋습니다.

var deviceAgent = navigator.userAgent.toLowerCase();

var isTouchDevice = Modernizr.touch || 
(deviceAgent.match(/(iphone|ipod|ipad)/) ||
deviceAgent.match(/(android)/)  || 
deviceAgent.match(/(iemobile)/) || 
deviceAgent.match(/iphone/i) || 
deviceAgent.match(/ipad/i) || 
deviceAgent.match(/ipod/i) || 
deviceAgent.match(/blackberry/i) || 
deviceAgent.match(/bada/i));

if (isTouchDevice) {
        //Do something touchy
    } else {
        //Can't touch this
    }

Modernizr을 사용하지 않으면 Modernizr.touch위 의 함수를('ontouchstart' in document.documentElement)

또한 사용자 에이전트를 테스트 iemobile하면보다 다양한 탐지 된 Microsoft 모바일 장치를 제공 할 수 있습니다 Windows Phone.

또한이 SO 질문을 참조하십시오


8
"뭔가를 할 민감한"를위한 보너스 포인트의 제비는 "이 건드릴 수 없어"
리 색슨

동일한 장치에 대해 여러 번 확인하고 하나만 사용할 수 있으면 여러 개의 Regexe를 수행합니다. 또한 대소 문자를 구분하지 않는 정규 표현식을 수행하지만 문자열은 이미 소문자입니다.
caesarsol

1
이것으로 충분해야합니다./(iphone|ipod|ipad|android|iemobile|blackberry|bada)/.test(window.navigator.userAgent.toLowerCase())
caesarsol

대소 문자를 구분하지 않고 소문자로 바꾸어야하는 이유가 있습니까? "iOS", "Android"또는 "IEMobile"은 언제 다른 케이스를 사용합니까?
Henrik N

14

우리는 modernizr 구현을 시도했지만 터치 이벤트 감지는 더 이상 일관성이 없습니다 (IE 10은 Windows 데스크탑에서 터치 이벤트를 가지며 IE 11은 터치 이벤트를 삭제하고 포인터 api를 추가했기 때문에 작동합니다).

그래서 우리는 사용자가 어떤 입력 유형을 가지고 있는지 모른다면 웹 사이트를 터치 사이트로 최적화하기로 결정했습니다. 이것은 다른 솔루션보다 더 안정적입니다.

우리의 연구에 따르면 대부분의 데스크톱 사용자는 클릭하기 전에 화면 위로 마우스를 가져 가면 클릭하거나 마우스를 갖기 전에이를 감지하고 동작을 변경할 수 있다고합니다.

이것은 코드의 단순화 된 버전입니다.

var isTouch = true;
window.addEventListener('mousemove', function mouseMoveDetector() {
    isTouch = false;
    window.removeEventListener('mousemove', mouseMoveDetector);
});

오늘날 컴퓨터에는 터치와 마우스가 모두 있습니다. 차별화해야합니다. 터치, 마우스 또는 둘 다인지 아는 것이 절대적입니다. 3 가지 상태.
vsync

1
예, 맞습니다. 그러나 이것은 매우 어렵습니다. 가장 좋은 경우 응용 프로그램은 모든 입력 컨트롤러에서 사용하도록 설계되었으며 사용자가 터치 스크린, 마우스, 키보드 또는 모두를 가지고 있는지 상관하지 않습니다.
Martin Lantzsch

1
사용자의 행동은 사용자가 어떤 종류의 장치를 가지고 있는지에 대한 실제 정보보다 가치가 있습니다. 사용자에게 마우스, 터치 스크린 및 키보드가 있다는 것을 알고 있다면 무엇입니까? 동작 (mousemove, touchmove, keydown 등)을 처리하십시오. 사용자는 "런타임"에서 입력 유형을 변경할 수 있습니다. 이는 다시로드하지 않고 8에서 5까지 사용되는 실제 응용 프로그램을 개발할 때 매우 어려운 문제입니다.
Martin Lantzsch

2
+1 실용적으로 이것은 나에게 가장 적합한 답변입니다. 예를 들어 데이터 그리드가 있습니다. 이 데이터 그리드에는 편집을 위해 터치하는 "편집 아이콘"또는 추가 옵션을위한 상황에 맞는 메뉴가 표시됩니다. 마우스 이동이 감지되면 아이콘을 제거하고 (격자에 공간 절약) 사용자가 두 번 클릭하거나 마우스 오른쪽 버튼으로 클릭 할 수 있습니다.
prograhammer

3
터치 장치의 크롬이 때때로
마우스 움직임을

9

일 바이올린

나는 이것을 이렇게 달성했다.

function isTouchDevice(){
    return true == ("ontouchstart" in window || window.DocumentTouch && document instanceof DocumentTouch);
}

if(isTouchDevice()===true) {
    alert('Touch Device'); //your logic for touch device
}
else {
    alert('Not a Touch Device'); //your logic for non touch device
}

창문 표면 태블릿을 감지하지 못함
Dan Beaulieu

@ DanBeaulieu 당신은 장치가 잘 작동 할 수 있습니까, Windows 전화가 잘 작동하기 때문에 QA : ED 인 응용 프로그램에서 사용 했으므로 다시 확인하고 대답을 업데이트 할 것입니다. 죄송합니다 불편을 끼쳐 드려
아미르 Shahzad

몇 년인지는 확실하지 않지만 동료에게 속한 Windows Surface Pro입니다. modernizr을 추가 한 후 작동하도록했습니다.
Dan Beaulieu

이것은 내 Windows 7 컴퓨터에서 터치가 아닌 것으로보고되었으며 터치 스크린이있는 Windows 8 랩톱 및 Android 4.4 MotoX 전화에서 터치합니다.
Clay Nichols 1

내 Mac의 Chrome (46)에서 오탐 (false positive)
Patrick Fabrizius

9

터치 스크린이 있는지 확인하는 것보다 더 좋은 방법이 있습니다. 사용 중인지 확인하는 것이 더 쉽습니다.

if (window.addEventListener) {
    var once = false;
    window.addEventListener('touchstart', function(){
        if (!once) {
            once = true;
            // Do what you need for touch-screens only
        }
    });
}

6

이것은 Windows Surface 태블릿에서도 잘 작동합니다 !!!

function detectTouchSupport {
msGesture = window.navigator && window.navigator.msPointerEnabled && window.MSGesture,
touchSupport = (( "ontouchstart" in window ) || msGesture || window.DocumentTouch &&     document instanceof DocumentTouch);
if(touchSupport) {
    $("html").addClass("ci_touch");
}
else {
    $("html").addClass("ci_no_touch");
}
}

4

위의 코드를 사용하여 터치 여부를 감지했기 때문에 fancybox iframe이 터치가 아닌 데스크탑 컴퓨터에 표시됩니다. blmstr의 코드 만 사용할 때 Android 4.0 용 Opera Mini가 여전히 비 터치 장치로 등록되고 있음을 알았습니다. (아무도 이유를 알고 있습니까?)

나는 다음을 사용하여 끝났다.

<script>
$(document).ready(function() {
    var ua = navigator.userAgent;
    function is_touch_device() { 
        try {  
            document.createEvent("TouchEvent");  
            return true;  
        } catch (e) {  
            return false;  
        }  
    }

    if ((is_touch_device()) || ua.match(/(iPhone|iPod|iPad)/) 
    || ua.match(/BlackBerry/) || ua.match(/Android/)) {
        // Touch browser
    } else {
        // Lightbox code
    }
});
</script>

단일 정규 표현식으로 단일 일치 호출을 사용하지 않는 이유를 설명해 주 /iPhone|iPod|iPad|Android|BlackBerry/시겠습니까?
user907860

Opera Mini는 장치 자체가 아닌 Opera 서버에서 렌더링을 수행하므로 다소 이상합니다.
bluesmoon

4

터치 감지를 시도하는 가장 큰 "gotcha"는 터치와 트랙 패드 / 마우스를 모두 지원하는 하이브리드 장치입니다. 사용자의 장치가 터치를 지원하는지 여부를 올바르게 감지 할 수 있더라도 실제로해야 할 일은 사용자가 현재 사용 중인 입력 장치를 감지하는 것 입니다. 이 도전에 대한 자세한 내용과 가능한 해결책이 있습니다. .

기본적으로 사용자가 방금 화면을 터치했는지 또는 마우스 / 트랙 패드를 대신 사용했는지 알아내는 방법 은 페이지에 a touchstartmouseover이벤트를 모두 등록하는 것입니다 .

document.addEventListener('touchstart', functionref, false) // on user tap, "touchstart" fires first
document.addEventListener('mouseover', functionref, false) // followed by mouse event, ie: "mouseover"

터치 동작은 이러한 이벤트를 모두 트리거하지만 전자 ( touchstart)는 항상 대부분의 장치에서 첫 번째입니다. 따라서이 예측 가능한 일련의 이벤트 can-touch를 고려하여 문서에서 현재 사용자 의 현재 입력 유형을 문서에 반영하기 위해 클래스를 문서 루트에 동적으로 추가하거나 제거하는 메커니즘을 작성할 수 있습니다 .

;(function(){
    var isTouch = false //var to indicate current input type (is touch versus no touch) 
    var isTouchTimer 
    var curRootClass = '' //var indicating current document root class ("can-touch" or "")
     
    function addtouchclass(e){
        clearTimeout(isTouchTimer)
        isTouch = true
        if (curRootClass != 'can-touch'){ //add "can-touch' class if it's not already present
            curRootClass = 'can-touch'
            document.documentElement.classList.add(curRootClass)
        }
        isTouchTimer = setTimeout(function(){isTouch = false}, 500) //maintain "istouch" state for 500ms so removetouchclass doesn't get fired immediately following a touch event
    }
     
    function removetouchclass(e){
        if (!isTouch && curRootClass == 'can-touch'){ //remove 'can-touch' class if not triggered by a touch event and class is present
            isTouch = false
            curRootClass = ''
            document.documentElement.classList.remove('can-touch')
        }
    }
     
    document.addEventListener('touchstart', addtouchclass, false) //this event only gets called when input type is touch
    document.addEventListener('mouseover', removetouchclass, false) //this event gets called when input type is everything from touch to mouse/ trackpad
})();

자세한 내용은 여기를 참조 하십시오 .


3

게시물을 확인하십시오. 터치 장치가 감지 될 때 수행해야 할 작업이나 터치 시작 이벤트가 호출 될 때 수행 할 작업에 대한 훌륭한 코드 스 니펫을 제공합니다.

$(function(){
  if(window.Touch) {
    touch_detect.auto_detected();
  } else {
    document.ontouchstart = touch_detect.surface;
  }
}); // End loaded jQuery
var touch_detect = {
  auto_detected: function(event){
    /* add everything you want to do onLoad here (eg. activating hover controls) */
    alert('this was auto detected');
    activateTouchArea();
  },
  surface: function(event){
    /* add everything you want to do ontouchstart here (eg. drag & drop) - you can fire this in both places */
    alert('this was detected by touching');
    activateTouchArea();
  }
}; // touch_detect
function activateTouchArea(){
  /* make sure our screen doesn't scroll when we move the "touchable area" */
  var element = document.getElementById('element_id');
  element.addEventListener("touchstart", touchStart, false);
}
function touchStart(event) {
  /* modularize preventing the default behavior so we can use it again */
  event.preventDefault();
}

3

장치가 터치 장치인지 확인하기 위해 화면 너비를 사용하지 마십시오. 699px보다 훨씬 큰 터치 스크린이 있습니다. Windows 8을 생각하십시오. Navigatior.userAgent는 잘못된 자세를 무시하는 것이 좋습니다.

Modernizr 에서이 문제 를 확인하는 것이 좋습니다 .

장치가 터치 이벤트를 지원하는지 또는 터치 장치인지 테스트하려고합니다. 불행히도, 그것은 같은 것이 아닙니다.


3

아니요, 불가능합니다. 어떤 주어진 방법으로도 오탐 (false positive)과 오탐 (false negative)이 생성되므로 우수한 답변은 부분적으로 만 나타납니다. 브라우저조차도 OS API로 인해 터치 스크린이 있는지 항상 알 수 없으며 브라우저 세션 동안 특히 KVM 유형 배열을 통해 사실이 변경 될 수 있습니다.

이 우수한 기사에서 자세한 내용을 참조하십시오.

http://www.stucox.com/blog/you-cant-detect-a-touchscreen/

이 기사에서는 터치 스크린을 감지하려는 가정을 다시 생각해 보면 잘못되었을 수 있습니다. (나는 내 ​​앱을 확인했고 내 가정은 실제로 잘못되었습니다!)

이 기사는 다음과 같이 결론을 맺습니다.

레이아웃의 경우 모든 사람이 터치 스크린을 가지고 있다고 가정합니다. 마우스 사용자는 터치 사용자가 작은 것을 사용하는 것보다 큰 UI 컨트롤을 훨씬 더 쉽게 사용할 수 있습니다. 호버 상태에서도 마찬가지입니다.

이벤트 및 상호 작용의 경우 누구나 터치 스크린이있을 수 있다고 가정하십시오. 키보드, 마우스 및 터치 상호 작용을 서로 구현하여 서로를 차단하지 않도록합니다.


3

이러한 작업 중 많은 것이 작동하지만 jQuery가 필요하거나 자바 스크립트 린터가 구문에 대해 불평합니다. 초기 질문 에이 문제를 해결하는 "JavaScript"(현대식이 아니라 jQuery가 아닌) 방법을 요구하는 것을 고려할 때마다 매번 작동하는 간단한 함수가 있습니다. 또한 최소한으로 얻을 수있는 정도입니다.

function isTouchDevice() {
    return !!window.ontouchstart;
}

console.log(isTouchDevice());

마지막으로 언급 할 이점은이 코드가 프레임 워크 및 장치에 구애받지 않는다는 것입니다. 즐겨!


function isTouchScreen() { return window.matchMedia('(hover: none)').matches;}이것은 나를 위해 일했기 때문에 Google이 나를 여기에 데려 왔을 때 바닐라 JS 스레드를 기대했기 때문에이 답변에 기여를 추가하고 있습니다.
Daniel Lavedonio de Lima

2

Chrome 24는 이제 Windows 8에서 터치 이벤트를 지원하는 것처럼 보입니다. 여기에 게시 된 코드는 더 이상 작동하지 않습니다. 브라우저에서 터치가 지원되는지 감지하는 대신 터치 및 클릭 이벤트를 모두 바인딩하고 하나만 호출해야합니다.

myCustomBind = function(controlName, callback) {

  $(controlName).bind('touchend click', function(e) {
    e.stopPropagation();
    e.preventDefault();

    callback.call();
  });
};

그런 다음 호출하십시오.

myCustomBind('#mnuRealtime', function () { ... });

도움이 되었기를 바랍니다 !



2

데스크탑 용 Firefox를 제외하고 지원되는 모든 브라우저 는 개발자가 터치 버튼을 클릭하더라도 반응 형 디자인을 지원하므로 데스크탑 용 Firefox를 제외하고는 항상 TRUE 입니다!

Mozilla가 다음 버전에서이 문제를 해결하기를 바랍니다.

Firefox 28 데스크탑을 사용하고 있습니다.

function isTouch()
{
    return !!("ontouchstart" in window) || !!(navigator.msMaxTouchPoints);
}

여전히 버전 32.0이며 아직 수정하지 않았습니다! 미친 것 같은. 왜 이것을 토글 할 수 없습니까? 이것은 항상 다음을 반환합니다. true(
vsync

2

jQuery v1.11.3

제공된 답변에 좋은 정보가 많이 있습니다. 그러나 최근에 나는 두 가지를 달성하기 위해 실제로 모든 것을 실제로 해결하기 위해 많은 시간을 보냈습니다.

  1. 사용중인 장치가 터치 스크린 유형 장치인지 감지하십시오.
  2. 장치가 탭되었음을 감지하십시오.

이 게시물과 Javascript가있는 터치 스크린 장치 감지 외에도 Patrick Lauke의 게시물이 매우 도움이되었습니다. https://hacks.mozilla.org/2013/04/detecting-touch-its-the-why-not-the-how /

코드는 다음과 같습니다.

$(document).ready(function() {
//The page is "ready" and the document can be manipulated.

    if (('ontouchstart' in window) || (navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0))
    {
      //If the device is a touch capable device, then...
      $(document).on("touchstart", "a", function() {

        //Do something on tap.

      });
    }
    else
    {
      null;
    }
});

중대한! 그만큼*.on( events [, selector ] [, data ], handler ) 방법에는 "touchstart"이벤트 또는 터치와 관련된 다른 이벤트를 처리 할 수있는 선택기, 일반적으로 요소가 있어야합니다. 이 경우 하이퍼 링크 요소 "a"입니다.

이제 하이퍼 링크 "a"요소에 대한 선택기를 사용하여 CSS를 사용하여 이러한 이벤트를 처리 할 수 ​​있으므로 JavaScript에서 일반 마우스 클릭을 처리 할 필요가 없습니다.

/* unvisited link */
a:link 
{

}

/* visited link */
a:visited 
{

}

/* mouse over link */
a:hover 
{

}

/* selected link */
a:active 
{

}

참고 : 다른 선택기도 있습니다 ...


1
var isTouchScreen = 'createTouch' in document;

또는

var isTouchScreen = 'createTouch' in document || screen.width <= 699 || 
    ua.match(/(iPhone|iPod|iPad)/) || ua.match(/BlackBerry/) || 
    ua.match(/Android/);

내가 생각하는 더 철저한 검사 일 것입니다.


3
ua언급하는 것이 좋습니다 navigator.userAgent. 또한 누군가가 전체 화면 모드가 아닌 브라우저를 열면 화면 너비를 감지하면 잘못된 결과를 초래할 수 있습니다.
HoLyVieR

1

나는 사용한다:

if(jQuery.support.touch){
    alert('Touch enabled');
}

jQuery Mobile 1.0.1에서


1

또한 페이지가 터치 스크린 장치에 표시되는지 여부를 Javascript로 감지하는 방법에 대한 다양한 옵션으로 많은 어려움을 겪었습니다. IMO는 현재 옵션을 올바르게 감지하기위한 실제 옵션이 없습니다. 브라우저는 데스크톱 컴퓨터에서 터치 이벤트를보고하거나 (OS는 터치 준비가되어 있기 때문에) 일부 솔루션이 모든 모바일 장치에서 작동하지는 않습니다.

결국, 나는 처음부터 잘못된 접근 방식을 따르고 있음을 깨달았습니다. 터치 및 비 터치 장치에서 페이지가 비슷하게 보일 경우 속성 감지에 대해 걱정할 필요가 없습니다. 내 시나리오는 터치 장치의 버튼에 대한 툴팁을 비활성화하려면 두 번 탭하면 버튼을 활성화하기 위해 한 번의 탭을 원했습니다.

내 솔루션은 뷰 를 리팩터링 하여 버튼 위에 툴팁이 필요하지 않았으며 결국 Javascript에서 터치 장치를 감지 할 필요가 없었습니다. 모두 단점이 습니다 .


1

Modernizer를 설치하고 간단한 터치 이벤트를 사용할 수 있습니다. 이것은 매우 효과적이며 Windows 표면을 포함하여 테스트 한 모든 장치에서 작동합니다!

jsFiddle을 만들었습니다

function isTouchDevice(){
    if(Modernizr.hasEvent('touchstart') || navigator.userAgent.search(/Touch/i) != -1){
         alert("is touch");
            return true;
         }else{
            alert("is not touch");
            return false;
    }
}

3
SO에 오신 것을 환영합니다! 주석 처리되지 않은 코드와 같은 코드 자체는 답을 거의 구성하지 않습니다. 스 니펫에 대한 설명을 추가하여이 답변을 개선 할 수 있습니다.
ebarr

1

실제적인 답변은 상황을 고려한 것으로 보입니다.

1) 공개 사이트 (로그인 없음)
두 옵션을 함께 사용하도록 UI를 코딩하십시오.

2) 로그인 사이트
로그인 폼에서 마우스 이동이 발생했는지를 캡쳐하여 숨겨진 입력에 저장합니다. 이 값은 로그인 자격 증명과 함께 전달되어 사용자 세션에 추가됩니다. 되므로 기간 동안 사용할 수 있습니다.

로그인 페이지에만 추가하는 Jquery :

$('#istouch').val(1); // <-- value will be submitted with login form

if (window.addEventListener) {
    window.addEventListener('mousemove', function mouseMoveListener(){
        // Update hidden input value to false, and stop listening
        $('#istouch').val(0); 
        window.removeEventListener('mousemove', mouseMoveListener);
    });
} 

(대답에서 @Dave Burt에 +1, @Martin Lantzsch에 +1)


1

문제

터치와 마우스 입력의 조합을 사용하는 하이브리드 장치로 인해 동적으로 가능해야합니다 사용자가 터치 사용자인지 여부를 제어하는 ​​상태 / 변수를 변경할 있어야합니다.

터치 장치도 발사 mousemove 탭에서 작동합니다.

해결책

  1. 로드시 터치가 거짓이라고 가정합니다.
  2. touchstart이벤트가 발생할 때까지 기다린 다음 true로 설정하십시오.
  3. touchstart가 시작된 경우 mousemove 핸들러를 추가하십시오.
  4. 두 mousemove 이벤트 발생 시간이 20ms 미만인 경우 마우스를 입력으로 사용한다고 가정하십시오. 더 이상 필요하지 않으므로 이벤트를 제거하십시오. mousemove는 마우스 장치에 대한 비싼 이벤트입니다.
  5. 터치 스타트가 다시 시작 되 자마자 (사용자는 터치를 다시 사용했습니다) 변수는 다시 true로 설정됩니다. 그리고 역동적 인 방식으로 결정되도록 프로세스를 반복하십시오. 기적에 의해 mousemove가 터무니없이 빠르게 두 번 터치되면 (내 테스트에서 20ms 이내에는 불가능합니다), 다음 터치 스타트는 다시 true로 설정합니다.

Safari iOS 및 Android 용 Chrome에서 테스트되었습니다.

참고 : MS Surface 등의 포인터 이벤트는 100 % 확실하지 않습니다.

코드 펜 데모


const supportsTouch = 'ontouchstart' in window;
let isUsingTouch = false;

// `touchstart`, `pointerdown`
const touchHandler = () => {
  isUsingTouch = true;
  document.addEventListener('mousemove', mousemoveHandler);
};

// use a simple closure to store previous time as internal state
const mousemoveHandler = (() => {
  let time;

  return () => {
    const now = performance.now();

    if (now - time < 20) {
      isUsingTouch = false;
      document.removeEventListener('mousemove', mousemoveHandler);
    }

    time = now;
  }
})();

// add listeners
if (supportsTouch) {
  document.addEventListener('touchstart', touchHandler);
} else if (navigator.maxTouchPoints || navigator.msMaxTouchPoints) {
  document.addEventListener('pointerdown', touchHandler);
}

1

사실, 나는이 질문을 연구하고 모든 상황을 고려합니다. 내 프로젝트에서도 큰 문제이기 때문입니다. 따라서 아래 기능에 도달하면 모든 장치에서 모든 버전의 모든 브라우저에서 작동합니다.

const isTouchDevice = () => {
  const prefixes = ['', '-webkit-', '-moz-', '-o-', '-ms-', ''];
  const mq = query => window.matchMedia(query).matches;

  if (
    'ontouchstart' in window ||
    (window.DocumentTouch && document instanceof DocumentTouch)
  ) {
    return true;
  }
  return mq(['(', prefixes.join('touch-enabled),('), 'heartz', ')'].join(''));
};

힌트 : 확실히,isTouchDevice그냥boolean값을반환합니다.


0

익스텐트 jQuery support객체 :

jQuery.support.touch = 'ontouchend' in document;

이제 다음과 같이 어디서나 확인할 수 있습니다.

if( jQuery.support.touch )
   // do touch stuff

0

이것은 지금까지 잘 작동하는 것 같습니다.

//Checks if a touch screen
is_touch_screen = 'ontouchstart' in document.documentElement;

if (is_touch_screen) {
  // Do something if a touch screen
}
else {
  // Not a touch screen (i.e. desktop)
}

0

마우스를 장착하면 페이지가 준비된 후 사용자가 아무 클릭없이 마우스를 최소한의 거리만큼 움직인다고 상당히 높은 히트 레이트 (실제로 100 %라고 말할 수 있음)로 가정 할 수 있습니다. 아래 메커니즘이이를 감지합니다. 감지되면 터치 지원이 누락되었거나 지원되는 경우 마우스를 사용할 때 중요하지 않은 것으로 간주합니다. 터치 장치가 감지되지 않으면 가정합니다.

편집 이 방법은 모든 목적에 맞지는 않을 수 있습니다. 이미지 뷰어와 같이로드 된 페이지에서 사용자 상호 작용을 기반으로 활성화되는 기능을 제어하는 ​​데 사용할 수 있습니다. 아래 코드는 mousemove 이벤트가 마우스가없는 장치에서 현재 눈에 띄는 상태로 유지되도록합니다. 다른 접근 방식이 더 나을 수 있습니다.

대략 다음과 같이 진행됩니다 (jQuery에는 미안하지만 순수한 Javascript에서는 비슷합니다).

var mousedown, first, second = false;
var ticks = 10;
$(document).on('mousemove', (function(e) {
    if(UI.mousechecked) return;
    if(!first) {
        first = e.pageX;
        return;
        }
    if(!second && ticks-- === 0) {
        second = e.pageX;
        $(document).off('mousemove'); // or bind it to somewhat else
        }
    if(first  && second  && first !== second && !mousedown){
        // set whatever flags you want
        UI.hasmouse = true;
        UI.touch = false;
        UI.mousechecked = true;
    }

    return;
}));
$(document).one('mousedown', (function(e) {
    mousedown = true;
    return;
}));
$(document).one('mouseup', (function(e) {
    mousedown = false;
    return;
}));
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.