How do I detect whether a browser supports mouseover events?
Asked Answered
B

5

14

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 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.

Birch answered 10/1, 2011 at 3:24 Comment(4)
I think your question needs to be rephrased, since the iPad does support onhover theoretically but the input makes it impossible. So you're question should be: How can I detect wether the user has the hardware possibilities of hovering over an item?Frasch
maybe this can give you a start: #3975327Sardonyx
@nightcracker - From the point of view of the site (and me), it doesn't matter whether the hardware is capable of supporting hover - the only thing that matters is whether there's a meaningful onmouseover or onmouseout hook. I'll clarify in the question.Birch
@amosriviera - Thanks for that, some interesting stuff in that question. There's one answer that gives me an option for iPad, but nothing cross-browser.Birch
K
11
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.

Keeling answered 10/1, 2011 at 3:43 Comment(6)
Does this work for all/most touch devices? Android phones and tablets, Nokia touchscreens, as well as iWhatevers?Birch
Android & iThings 99.9%, Symbian? Yes from some QtWebKit version on but don't ask me which version of Symbian that would be.Keeling
Are you looking for alternatives? Consider onmousemove but this will require timeout and what not and might end up being emulated on some platform.Keeling
It should be noted that a device that supports touch events is not necessarily hover-challenged: they may support more than one way to interact with it (e.g., pen).Unclog
IE10 and 11 on the Surface tablet do not support touch events even though the Surface is a touch device.Alleviator
If a device supports touch, then providing only hover behavior when it is meaningfully supported makes the device that much less useful because users relying on touch features would still not (be able to) use hover. So detecting touch, imho, is a valid approach.Unclog
S
18

This method catches more devices/browsers

try {
   document.createEvent("TouchEvent");
   alert(true);
}
catch (e) {
   alert(false);
}

Read more

Sausauce answered 6/1, 2012 at 13:29 Comment(3)
I didn't get the accepted answer to work at all in the androids I've been testing with, but this one works great.Diopside
The accepted answer did nothing for me, either, but this one did the trick! Thanks, Johan.Viscounty
False positive on the latest version of Chrome (v. 32, Win7, no touch screen).Daughterinlaw
K
11
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.

Keeling answered 10/1, 2011 at 3:43 Comment(6)
Does this work for all/most touch devices? Android phones and tablets, Nokia touchscreens, as well as iWhatevers?Birch
Android & iThings 99.9%, Symbian? Yes from some QtWebKit version on but don't ask me which version of Symbian that would be.Keeling
Are you looking for alternatives? Consider onmousemove but this will require timeout and what not and might end up being emulated on some platform.Keeling
It should be noted that a device that supports touch events is not necessarily hover-challenged: they may support more than one way to interact with it (e.g., pen).Unclog
IE10 and 11 on the Surface tablet do not support touch events even though the Surface is a touch device.Alleviator
If a device supports touch, then providing only hover behavior when it is meaningfully supported makes the device that much less useful because users relying on touch features would still not (be able to) use hover. So detecting touch, imho, is a valid approach.Unclog
B
10

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 document body that activates a "has hover" state (e.g. adding a class user-can-mouseover to body) 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 that mousemove and a touchend 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 the mousemove.
  • Have the mousemove event unbind these touchstart and touchend 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:

  1. Initially, the user is browsing the web using touch and swipe.
  2. They reach your application, swipe up and down using touch while understanding what it is. So far, the "can hover" condition isn't active.
  3. 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.
  4. 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:

  1. The page loads.
  2. The user moves the mouse while doing anything, immediately triggering the mouse move event
  3. The "can hover" state is triggered immediately
Bohemia answered 13/9, 2016 at 16:29 Comment(0)
M
5

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
Milagro answered 11/6, 2020 at 16:24 Comment(1)
Great answer. I just tried it out on a Samsung Galaxy Note 8 and the linked "hover" example worked perfectly with the pen (yellow on hover), but the "any-hover" didn't (no response on hover). Strange because if anything I'd have expected it to be the other way around since the pen is a secondary input method after touch?Bohemia
S
3

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.

Suzannesuzerain answered 2/8, 2017 at 16:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.