Как лучше всего обнаружить устройство с «сенсорным экраном» с помощью JavaScript? - PullRequest
375 голосов
/ 27 января 2011

Я написал плагин jQuery для использования на настольных и мобильных устройствах. Я задавался вопросом, есть ли способ с JavaScript, чтобы обнаружить, если устройство имеет возможность сенсорного экрана. Я использую jquery-mobile.js для обнаружения событий сенсорного экрана, и он работает на iOS, Android и т. Д., Но я также хотел бы написать условные операторы, основанные на том, имеет ли устройство пользователя сенсорный экран.

Это возможно?

Ответы [ 36 ]

613 голосов
/ 27 января 2011

Вы пробовали использовать эту функцию?(Это то же самое, что использовал Modernizr.)

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

ОБНОВЛЕНИЕ 1

document.createEvent("TouchEvent") начали возвращать true в последнем Chrome (ст. 17).Modernizr обновил это некоторое время назад. Проверьте тест Modernizr здесь .

Обновите вашу функцию, чтобы она работала:

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

ОБНОВЛЕНИЕ 2

Я обнаружил, что вышеупомянутое не работает на IE10 (возвращая false на MS Surface).Вот исправление:

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

UPDATE 3

'onmsgesturechange' in window вернет true в некоторых версиях IE для настольных компьютеров, так что это ненадежно.Это работает немного более надежно:

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

ОБНОВЛЕНИЕ 2018

Время идет, и есть новые и лучшие способы проверить это.Я в основном извлек и упростил способ проверки Modernizr:

function is_touch_device() {
  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);
}

Здесь они используют нестандартную функцию touch-enabled медиазапросов, что я считаю довольно странной и плохой практикой.Но эй, в реальном мире, я думаю, это работает.В будущем (когда они поддерживаются всеми) эти функции медиазапроса могут дать вам те же результаты: pointer и hover.

Ознакомьтесь с источником того, как Modernizr делает это .

Хорошую статью, в которой объясняются проблемы с распознаванием касаний, см. В Stu Cox: сенсорный экран не обнаруживается .

137 голосов
/ 27 января 2011

Обновление: прочитайте ответ blmstr ниже, прежде чем использовать целую библиотеку обнаружения объектов в своем проекте. Обнаружение фактической сенсорной поддержки более сложное, и Modernizr охватывает только базовый вариант использования.

Modernizr - отличный и легкий способ обнаружения всех видов функций на любом сайте.

Он просто добавляет классы к элементу html для каждой функции.

Затем вы можете легко настроить эти функции в CSS и JS. Например:

html.touch div {
    width: 480px;
}

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

И Javascript (пример jQuery):

$('html.touch #popup').hide();
117 голосов
/ 20 ноября 2012

Поскольку Modernizr не обнаруживает IE10 в Windows Phone 8 / WinRT, простое кросс-браузерное решение:

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

Вам нужно проверять только один раз, поскольку устройство не будет внезапно поддерживать или не поддерживать касание, поэтому просто сохраните его в переменной, чтобы вы могли использовать его несколько раз более эффективно.

34 голосов
/ 15 марта 2013

Используя все комментарии выше, я собрал следующий код, который работает для моих нужд:

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, и я не смог найти решениедля этого браузера.

Надеюсь, кто-то найдет это полезным.

20 голосов
/ 21 марта 2012

Мне нравится этот:

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

alert(isTouchDevice());
17 голосов
/ 26 июня 2013

Если вы используете Modernizr , очень просто использовать 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

14 голосов
/ 04 июля 2014

Мы попробовали реализацию modernizr, но обнаружение сенсорных событий больше не является последовательным (IE 10 имеет сенсорные события на рабочем столе Windows, IE 11 работает, потому что упал сенсорные события и добавлен указатель api).

Поэтому мы решили оптимизировать веб-сайт как сенсорный, поскольку мы не знаем, какой тип ввода имеет пользователь. Это более надежно, чем любое другое решение.

Наши исследования говорят, что большинство пользователей настольных компьютеров перемещают курсор мыши по экрану, прежде чем щелкнуть, поэтому мы можем обнаружить их и изменить поведение, прежде чем они смогут что-либо щелкнуть или навести курсор.

Это упрощенная версия нашего кода:

var isTouch = true;
window.addEventListener('mousemove', function mouseMoveDetector() {
    isTouch = false;
    window.removeEventListener('mousemove', mouseMoveDetector);
});
9 голосов
/ 29 июня 2015

Есть что-то лучше, чем проверить, есть ли у них сенсорный экран, это проверить, используют ли они его, плюс это легче проверить.

if (window.addEventListener) {
    var once = false;
    window.addEventListener('touchstart', function(){
        if (!once) {
            once = true;
            // Do what you need for touch-screens only
        }
    });
}
9 голосов
/ 22 сентября 2014

Рабочая скрипка

Я достиг этого, вот так;

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
}
7 голосов
/ 17 октября 2018

С появлением функций интерактивных медиа вы можете просто:

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

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

...