8

In the past, the best method to check for the presence of a mouse was to look for touch event support. However, desktop Chrome now supports touch events, making this test misfire.

Is there a way to test directly for mouseover event support, rather than inferring it based on the presence of touch events?

Resolution: Here is the code that worked, based on the answer from AshleysBrain.

jQuery(function()
{
    // Has mouse
    jQuery("body").one("mousemove", function(e)
    {
        attachMouseEvents();
    });

    // Has touchscreen
    jQuery("body").one("touchstart", function(e)
    {
        // Unbind the mouse detector, as this will fire on some touch devices. Touchstart should always fire first.
        jQuery("body").unbind("mousemove");

        attachTouchEvents();
    });
});
Community
  • 1
  • 1
Luke Dennis
  • 14,212
  • 17
  • 56
  • 69
  • Great! Tried with playbook (RIM OS), and works fine first time, but on page refresh it detects mousemove (!?). However, attaching the test to some #id instead of body works perfectly. – MaxD Feb 17 '13 at 00:30

4 Answers4

5

You could do the opposite of the solution for detecting keyboard or touch input. Just wait for an actual touch event or mouse move event and decide based off that. If you check the presence of an event handler, the browser may indicate it has the event even if it is not currently running on hardware that supports it, so the only reliable thing to do is wait and see which actual events fire.

Community
  • 1
  • 1
AshleysBrain
  • 22,335
  • 15
  • 88
  • 124
  • Though I wish there was a cleaner way to do it, this turned out to be the solution that worked. I'm posting my code in the question for posterity. Thanks for your help! – Luke Dennis Feb 28 '12 at 23:27
1

You might want to think about using Modernizr, you could do something like the following using the Modernizer.hasEvent()(docs) method:

Modernizr.hasEvent("mouseover", document);
jabclab
  • 14,786
  • 5
  • 54
  • 51
  • I didn't want the overhead of all of Modernizr for this one specific task, but I was able to snip out the isEventSupported function and alter it to do what I needed. Thanks! – Luke Dennis Feb 24 '12 at 09:35
  • I spoke too soon. Modernizr.hasEvent("mouseover") evaluates to true on the iPhone. – Luke Dennis Feb 24 '12 at 09:46
0

I have try this and it's work.

<html>
<head>
    <script type="text/javascript">
        function isEventSupported(eventName) {
            var el = document.createElement("body"[eventName] || "div");
            var isSupported = "on" + eventName.toLowerCase() in el || top.Event && typeof top.Event == "object" && eventName.toUpperCase() in top.Event;
            el = null;
            return isSupported;
        }
    </script>
</head>

<body onload="alert(isEventSupported('mouseover'));">TEST mouseover event</body>
</html>

I took the function isEventSupported from http://www.strictly-software.com/eventsupport.htm

OammieR
  • 2,800
  • 5
  • 30
  • 51
  • This solution should work, but if you try this code on an iPhone, it still evaluates to true. I suspect that touch events are capable of triggering focus/mouseover under the hood, and so MobileSafari sees that event as being present even though there is no mouse. – Luke Dennis Feb 28 '12 at 22:43
-1

If web sites can detect that you're using a mobile browser as accurately as they do why can't you use the same technique to infer they don't have mouseover support?

The Muffin Man
  • 19,585
  • 30
  • 119
  • 191
  • What if it's an Android tablet with a mouse attached (which can be done)? I'm looking for a future-proof solution specific to mouse events. (I already have hacks in place checking for Chrome and mobile based on the user agent, but user agents aren't always trustworthy.) – Luke Dennis Feb 24 '12 at 09:24
  • Yikes, didn't know Android tablets had a mouse attachment option! – The Muffin Man Feb 24 '12 at 09:34
  • Crazy, right? It's an edge case, but if you plug in a mouse to an Android with a USB port, it works. – Luke Dennis Feb 24 '12 at 09:57