Как я могу обнаружить поддержку касания устройства в JavaScript?

в прошлом, при обнаружении, поддерживает ли устройство сенсорные события в JavaScript, мы могли бы сделать что-то вроде этого:

var touch_capable = ('ontouchstart' in document.documentElement);

Однако, Google Chrome (17.X. x+) возвращает true для вышеуказанной проверки, даже если основное устройство не поддерживает события касания. Например, запуск вышеуказанного кода в Windows 7 возвращает true, и, таким образом, если мы объединим его с чем-то вроде:

var start_evt = (touch_capable) ? 'ontouchstart' : 'onmousedown';

в Google Chrome событие никогда не запускается, так как мы привязываемся к ontouchstart. Короче, кто-нибудь знает надежный способ обойти это? В настоящее время я выполняю следующую проверку:

var touch_capable = ('ontouchstart' in document.documentElement && navigator.userAgent.toLowerCase().indexOf('chrome') == -1)

что далеко от идеала...

4 ответов


правильный ответ-обрабатывать и типы событий - они не взаимоисключающие.

для более надежного теста для поддержки касания, также ищите window.DocumentTouch && document instanceof DocumentTouch, который является одним из тестов, используемых Modernizr

еще лучше, просто используйте Modernizr самостоятельно и сделайте это обнаружение функций для вас.

обратите внимание, что вы не можете предотвратить ложные срабатывания, поэтому моя первая строка выше-у вас получил для поддержки оба.


это модификация того, как Modernizr выполняет сенсорное обнаружение, с дополнительной поддержкой для работы с сенсорными устройствами IE10+.

var isTouchCapable = 'ontouchstart' in window ||
 window.DocumentTouch && document instanceof window.DocumentTouch ||
 navigator.maxTouchPoints > 0 ||
 window.navigator.msMaxTouchPoints > 0;

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

ваш пробег может варьироваться:

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

обновление: Совет: не используйте touch-возможность обнаружения и определения режима работы интерфейса вместо этого используйте прослушиватели событий. Дизайн для события click/touch/keyup, а не устройства, обнаружение сенсорных возможностей обычно используется для сохранения расхода ЦП/памяти при добавлении прослушивателя событий. Один пример того, где сенсорное обнаружение может быть полезным и уместным:

if (isTouchCapable) {
    document.addEventListener('touchstart', myTouchFunction, false); 
}

рекомендуется использовать хорошо проверенный (и кросс-браузер) касания тест Modernizr это.

С их сайта:

// bind to mouse events in any case

if (Modernizr.touch){
   // bind to touchstart, touchmove, etc and watch `event.streamId`
} 

http://modernizr.github.com/Modernizr/touch.html


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

в coffescript это будет выглядеть так;

           hasTouch = false
           mouseIsDown = false
           @divs.on "touchstart", (e)->
              hasTouch = true
              touchstart(e.timeStamp,e.originalEvent.touches[0].pageX);
              return true
           @divs.on "mousedown", (e)->
              mouseIsDown = true;
              touchstart(e.timeStamp,e.clientX) if not hasTouch
              return true

           @divs.on 'touchmove', (e) ->
              touchmove(e.timeStamp,e.originalEvent.touches[0].pageX);
              return true;
           @divs.on 'mousemove', (e) ->
              touchmove(e.timeStamp,e.clientX) if mouseIsDown and not hasTouch 
              return true;

           @divs.on 'touchend', (e) ->
              touchend();
              return true
           @divs.on 'mouseup', (e) ->
              mouseIsDown = false;
              touchend() if not hasTouch
              return true

просто определите функции для touchstart,move и end содержащий фактическую логику....