Let's assume I have a web page which has some onmouseover javascript behaviour to drop down a menu (or something similar)
Obviously, this isn't going to work on a touch device like the iPad or smartphones.
How can I detect whether the browser supports hover events like onmouseover or onmouseout and the :hover pseudotag in CSS?
Note: I know that if I'm concerned about this I should write it a different way, but I'm curious as to whether detection can be done.
Edit: When I say, "supports hover events", I really mean, "does the browser have a meaningful representation of开发者_如何学Go hover events". If the hardware supports it but the software doesn't (or vice versa), there's no meaningful representation. With the exception of some upcoming tech, I don't think any touch devices have a meaningful representation of a hover event.
This method catches more devices/browsers
try {
document.createEvent("TouchEvent");
alert(true);
}
catch (e) {
alert(false);
}
Read more
var supportsTouch = (typeof Touch == "object");
Just detect if it's a touch device and then do your special stuff. This is the simplest approach since most touch devices emulate mouse events but no mouse driven device emulates touch events.
Update: Considering how many devices there are now a days and Johan's comments I'd recommend simply using Modernizr.
It's 2016 and plenty of devices have both touch and mouse-like inputs for several years now. "Can't touch" is not a good way to judge "Can mouseover". To give just a few examples:
- "Active pen" digitizer devices like Galaxy Note phones and tablets (Android), Microsoft Surface (Windows) and Wacom Cintiq (Mac/Windows/Android), and I believe the iPad Pro too, where the pen works like a mouse and can "air hover" when around 1cm from the screen
- Windows laptops / hybrids with touchscreens plus and convential laptop trackpads etc
- Touchscreen monitors that can be attached to any PC and used with a mouse
So a user could be unable to hover one minute, then, on the same device, without refreshing the page, they pull the pen out of their Galaxy Note and (assuming it doesn't catch fire) they suddenly are using hover in their interaction, and they expect it to Just Work.
If you need to know if your user a) can use and b) currently is using a device that enables them to conveniently mousover things, you could:
- Bind a
mousemove
event to your documentbody
that activates a "has hover" state (e.g. adding a classuser-can-mouseover
tobody
) if a mousemove-triggering cursor is moving, and then immediately unbinds itself so it only happens once. - Also bind a
touchstart
event that temporarily deactivates thatmousemove
and atouchend
that reactivates it, so that, on browsers that trigger mouse events on touch (quite common on Android and Windows), normal touch scrolling doesn't trigger themousemove
. - Have the
mousemove
event unbind thesetouchstart
andtouchend
events for good housekeeping
This would then cause the "can hover" state to be triggered any time a user starts using an input device that behaves like a mouse.
For example, taking a hybrid device:
- Initially, the user is browsing the web using touch and swipe.
- They reach your application, swipe up and down using touch while understanding what it is. So far, the "can hover" condition isn't active.
- They decide this is one of those cases where they want more accuracy than their fat fingers allow, so they pull out the digitizer pen or reach for their mouse.
- This causes the cursor to move across the page without an unended touch event having happened, so your "can hover" condition is triggered
...and taking an old-school desktop workstation with a mouse:
- The page loads.
- The user moves the mouse while doing anything, immediately triggering the mouse move event
- The "can hover" state is triggered immediately
Another approach for non-legacy browsers is taking advantage of media queries hover and any-hover
matchMedia('(hover: hover)').matches; // Primary device can hover
matchMedia('(hover: none)').matches; // Primary device cannot hover
matchMedia('(any-hover: hover)').matches; // At least one of the connected devices can hover
matchMedia('(any-hover: none)').matches; // None of the connected devices can hover
Set of functions based on user568458's response that allows you to turn on/off :hover styles for touch devices (I haven't tried it on all devices):
function detectMouseMove() {
$(document).one('mousemove', function() {
$('body').addClass('hoverActive');
detectTouchEvent();
});
}
function detectTouchEvent() {
$(document).one('touchstart', function() {
$('body').removeClass('hoverActive');
detectMouseMove();
});
}
Then you can just use .hoverActive in your stylesheet before any :hover selectors to prevent mobile browsers from trying to display the hover state.
精彩评论