Как я могу обнаружить поддержку сенсорного экрана в 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)
Что далеко от идеала...
Ответы
Ответ 1
Правильный ответ - обрабатывать оба типа событий - они не являются взаимоисключающими.
Для более надежного тестирования сенсорной поддержки также найдите window.DocumentTouch && document instanceof DocumentTouch
, который является одним из тестов, используемых Modernizr
Еще лучше, просто используйте Modernizr самостоятельно, и пусть это сделает обнаружение функции для вас.
Обратите внимание, что вы не можете предотвратить ложные срабатывания, поэтому моя первая строка выше - вы должны поддерживать оба.
Ответ 2
Это модификация того, как Modernizr выполняет сенсорное обнаружение, с дополнительной поддержкой работы с сенсорными устройствами IE10 +.
var isTouchCapable = 'ontouchstart' in window ||
window.DocumentTouch && document instanceof window.DocumentTouch ||
navigator.maxTouchPoints > 0 ||
window.navigator.msMaxTouchPoints > 0;
Он не является надежным, поскольку обнаружение сенсорного устройства, по-видимому, невозможно.
Ваш пробег может варьироваться:
- Старые сенсорные устройства только эмулируют события мыши.
- Некоторые браузеры и настройки ОС могут включать сенсорные API, если сенсорный экран не подключен.
- В гибридной среде mouse/touch/trackpad/pen/keyboard это не указывает, какой вход используется, только в том, что браузер трогателен - он обнаруживает, может ли браузер принимать или эмулировать сенсорный ввод. Например, пользователь может в любой момент переключиться с использования мыши на касание экрана на сенсорном ноутбуке или планшете, подключенном к мыши.
Update:
Совет. Не используйте обнаружение сенсорных возможностей для управления и указания поведения пользовательского интерфейса, вместо этого использовать прослушиватели событий. Дизайн для события click/touch/keyup, а не устройства, обнаружение сенсорной способности обычно используется для сохранения затрат процессора/памяти на добавление прослушивателя событий. Один из примеров того, где обнаружение касания может быть полезным и целесообразным:
if (isTouchCapable) {
document.addEventListener('touchstart', myTouchFunction, false);
}
Ответ 3
Вам следует рассмотреть возможность использования хорошо протестированного (и кросс-браузерного) тестирования TouchPress.
Со своего сайта:
// 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
Ответ 4
Ну, старый вопрос, но, чтобы сделать это без библиотеки, я создал следующее решение - просто позвольте событиям говорить для себя - когда вы видите события 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
, содержащие фактическую логику....