I\'m developing a webapp (not a website with pages of interesting text) with a very different interface for touch (your finger hides the screen when you click) and mouse (re
A simple solution in jQuery to detect mouse usage, which solves the issue where mobile devices also trigger 'mousemove' event. Simply add a touchstart listener to remove the mousemove listener, so that it doesn't get triggered on touch.
$('body').one('touchstart.test', function(e) {
// Remove the mousemove listener for touch devices
$('body').off('mousemove.test');
}).one('mousemove.test', function(e) {
// MOUSE!
});
Of course, the device could still be touch AND mouse, but the above will guarantee that a real mouse was used.
Have a look at modenizr one of its features is touch
http://modernizr.com/docs/#features-misc
While I've not tested fully it seems to work very well
Also this is linked from the modernizr page http://www.html5rocks.com/en/mobile/touchandmouse/
Since you're planning to offer a way to switch between the interfaces anyway, would it be feasible to simply ask the user to click a link or a button to "enter" the correct version of the application? Then you could remember their preference for future visits. It's not high-tech, but it's 100% reliable :-)
It is generally a better idea to detect if the mouseover function is supported rather than detecting the OS/browser type. You can do that simply by the following:
if (element.mouseover) {
//Supports the mouseover event
}
Be sure that you don't do the following:
if (element.mouseover()) {
// Supports the mouseover event
}
The latter would actually call the method, rather than check for its existence.
You can read up more here: http://www.quirksmode.org/js/support.html
@Wyatt's answer is great and gives us a lot to think about.
On my case, I chose to listen for the first interaction, to only then set a behavior. So, even if the user has a mouse, I will treat as touch device if first interaction was a touch.
Considering the given order in which events are processed:
We can assume that if mouse event gets triggered before touch, it is a real mouse event, not an emulated one. Example (using jQuery):
$(document).ready(function() {
var $body = $('body');
var detectMouse = function(e){
if (e.type === 'mousedown') {
alert('Mouse interaction!');
}
else if (e.type === 'touchstart') {
alert('Touch interaction!');
}
// remove event bindings, so it only runs once
$body.off('mousedown touchstart', detectMouse);
}
// attach both events to body
$body.on('mousedown touchstart', detectMouse);
});
That worked for me
As others have pointed out, definitively detecting whether or not they have a mouse is unreliable. This can easily change, depending on the device. It's definitely something you cannot do reliably with a boolean true or false, at least on a document scale.
Touch events and mouse events are exclusive. So this can help somewhat on taking different actions. The problem is the touch events are closer to the mouse up/down/move events, and also trigger a click event.
From you question you say you want to have a hover to preview. Beyond that I don't know any other specifics about your interface. I'm assuming that with the lack of a mouse you want a tap to preview, while a click does a different action because of the hover preview.
If that is the case you can take somewhat of a lazy approach to detection:
An onclick event will always be preceded by an onmouseover event with a mouse. So make a note that the mouse is on top of the element that has been clicked.
You could do this with a document-wide onmousemove event. You can use event.target
to record which element the mouse is residing on. Then inside your onclick events you can check to see whether or not the mouse is actually over the element being clicked (or a child of the element).
From there you can choose either to rely on the click event for both and take an A or B action depending on the result. The B action could be nothing if some touch devices don't emit a click event (instead you would have to rely on ontouch* events).