In the past, when detecting whether a device supports touch events in JavaScript, we could do something like this:
var touch_capable = ('ontouchstart' in document.documentElement);
However, Google Chrome (17.x.x+) returns true
for the above check, even if the underlying device does not support touch events. For example, running the above code on Windows 7 returns true, and thus if we combine it with something like:
var start_evt = (touch_capable) ? 'ontouchstart' : 'onmousedown';
On Google Chrome, the event is never fired since we're binding to ontouchstart
. In short, does anyone know a reliable way to circumvent this? I am currently running the following check:
var touch_capable = ('ontouchstart' in document.documentElement && navigator.userAgent.toLowerCase().indexOf('chrome') == -1)
Which is far from ideal...
The correct answer is to handle both event types - they're not mutually exclusive.
For a more reliable test for touch support, also look for window.DocumentTouch && document instanceof DocumentTouch
which is one of the tests used by Modernizr
Better yet, just use Modernizr yourself and have it do the feature detection for you.
Note though that you cannot prevent false positives, hence my first line above - you've got to support both.
This is a modification of how Modernizr performs touch detection, with added support to work with IE10+ touch devices.
var isTouchCapable = 'ontouchstart' in window ||
window.DocumentTouch && document instanceof window.DocumentTouch ||
navigator.maxTouchPoints > 0 ||
window.navigator.msMaxTouchPoints > 0;
It's not foolproof since detecting a touch device is apparently an impossibility .
Your mileage may vary:
Update: A tip: Do not use touch-capability detection to control & specify UI behaviors, use event listeners instead . Design for the click/touch/keyup event, not the device, touch-capability detection is typically used to save the cpu/memory expense of adding an event listener. One example of where touch detection could be useful and appropriate:
if (isTouchCapable) {
document.addEventListener('touchstart', myTouchFunction, false);
}
You should consider using the well tested (and cross-browser) Modernizr's touch test.
From their site:
// bind to mouse events in any case
if (Modernizr.touch){
// bind to touchstart, touchmove, etc and watch `event.streamId`
}
Well old question, but having to do this without a library, I created the following solution -- simply let the events talk for them self -- when you see the touch
events, just disable the processing of the mouse
events.
In coffescript is would look like this;
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
The just define functions for touchstart
, move
and end
containing the actual logic....
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.