Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mouseover sometimes fires instead of touchstart - why?

I have found a very strange behavior that I cannot explain. Want to do the following:

A handler needs to react to a touchstart or mouseover event, depending on the type of input device. Note that I want to support hybrid devices (with both mouse and touchscreen) and I cannot rely on pointer events.

Now, I just setup both touchstart and mouseoverevents. And for the most part it works just fine. Also use preventDefault to prohibit simulated "mouse" events firing after touch events. But what is totally confusing to me is that sometimes there is a still a mouseover event occuring, and if I remove the preventDefault, it even seems that the mouseoveris firing instead of a touchstart. Why oh why is this happening?

Furthermore, this is reproducible with both Android and iOS! Though it seems to be more easily triggered with Android (using Chrome).

I have prepared a little testcase so you can try for yourselves. Note that this behavior seems only triggered when you tap somewhere on the border between the red DIV (which has the events) and the background. Just tapping in the center works 100%. And you may need more or less tries until it happens.

Any help greatly appreciated!

<!DOCTYPE html>
<html>

<head>
  <title>Touchtest</title>
  <style>
    body {
      background: #222;
      color: white;
      position: relative;
      font-size: .9em;
      font-family: Arial, Helvetica, sans-serif;
    }
    #test {
      position: fixed;
      top: 100px;
      right: 100px;
      bottom: 100px;
      left: 100px;
      background: red;
    }
  </style>
</head>

<body>
  <div id="test"></div>
  <script type="text/javascript">
    function testEvent(event) {
      console.log("testEvent", event);
      if (event.type === "mouseover") {
        alert("MOUSEOVER DETECTED");
      }
      event.preventDefault();
    }

    var ele = document.getElementById("test");
    ele.addEventListener("touchstart", testEvent);
    ele.addEventListener("mouseover", testEvent);
  </script>
</body>

</html>
like image 538
frontend_dev Avatar asked Jan 13 '17 00:01

frontend_dev


2 Answers

I've poked around your example a bit and it seems like a bug in Chrome. I couldn't reproduce it in Firefox. You can reproduce it in Chrome developer tools on desktop and in fact I've found a way to reproduce it in a 100% of cases:

  • open dev tools and switch to device mode
  • place the circle cursor on the edge of red rectangle so that the center of the cursor is outside of the red rectangle chrome dev tool cursor sorry for the image quality, I can't capture this cursor with a screenshot
  • click
  • for it to work the next time, you have to first click on the black background away from red rectangle

So it seems like this happens when the center of the touch is outside of the rectangle, but the radius of the touch overlaps the rectangle. That said, I'm not sure what you can do here except file a bug report

like image 136
jetpackpony Avatar answered Sep 29 '22 05:09

jetpackpony


Mouse events (mouseover, mouseout, mousedown, mouseup, mousemove, etc) are specific to the mouse input device.

The mouseover javascript event would translate to the touchenter touch events. This events is part of a W3C draft (currently, just Firefox support), so if you want to use it, you must implement your onmouseover feature using touchmove event and looking at the coordinates and to see if they overlap with the coordinates of your html element.

I think that it helps you.

like image 27
Nedim Hozić Avatar answered Sep 29 '22 05:09

Nedim Hozić