1

I have a problem with the way browsers are handling mouseover and mouseleave events on touch devices.

I have one element A which shows and hides another Element B when you hover the mouse. Element B is a button with a click event. This is perfectly fine when using a mouse but when using touch input there is no mouseover of course. Browsers automaticly handle this the way that when you tap once on the element the mouseover event is fired and when you tap anywhere else on the screen the mouseleave event is fired (which makes sense most of the time).

Now my problem is that both events are fired at once with just one tap. And I'm unable to find a way around that. There seems to be no way to tell if the input was from a mouse or touch input.

I've put together a simple jsfiddle showcasing the problem: https://jsfiddle.net/djmpx1q4/1/

$("#outer").hover(function(){
 show();
}, function(){
 hide();
});

function show()
{
 $("#inner").css('display', 'block');
  $("#inner").on('click', function(){
   alert('hello');
  });
}

function hide()
{
 $("#inner").css('display', 'none');
  $("#inner").off('click');
}
#outer {
  padding:50px;
  width:200px;
  height: 200px;
  background-color: #FFFFFF;
}

#border {
  border: 1px solid black;
  width:100%;
  height:100%;
}

#inner {
  display: none;
  width:100%;
  height:100%;
  background-color: #CC0000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="outer">
<div id="border">
<div id="inner">

</div>
</div>
</div>

I need that to be 2 taps, first one to show the red box and second one to fire the click event while keeping the mouseover behavior for mouse users.

I'm really not sure what is exactly happening there. The element is not displayed and has no event attached in the moment the user taps there for the first time and still the event is fired.

1 Answers1

0

Try adding the following method to your code:

function detectMobile() {
  try {
    document.createEvent("TouchEvent");
    return true;
  } catch (e) {
    return false;;
  }
}

This method will attempt raise a touch event. You can then use it to determine if the user is using a touch-enabled device and adjust your code accordingly.

See this JSFiddle for a (somewhat choppy) example.

  • 1
    This will stop 'mouse' click events on a device that allows multiple pointer/input types such as a Microsoft Surface :( – Submachine23 Aug 06 '16 at 06:18
  • `(typeof Touch === 'object')` might be a better way to detect touchscreens, but that's still a bad approach because touchscreens and mouse-like input aren't mutually exclusive, plenty of devices use both (e.g. touchscreen Windows laptops, Galaxy Note phones when pen is used) – user56reinstatemonica8 Sep 13 '16 at 16:01