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 mouseover
events. 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 mouseover
is 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>
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 mouseover
events. 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 mouseover
is 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>
Share
Improve this question
asked Jan 13, 2017 at 0:59
frontend_devfrontend_dev
1,71914 silver badges28 bronze badges
5
- If you will look at the mousedown event coordinates you will find that when you click on the edges (just outside) in the mobile mode using Chrome the coordinates are not correct. – Rewanth Tammana Commented Feb 3, 2017 at 8:44
- Hey there I can't reproduce your bug in chrome, jsfiddle/xvtgc36r/1 – Jonathan Newton Commented Feb 3, 2017 at 9:26
- Hmm, your code differs a bit. Also make sure you test on a touch device. – frontend_dev Commented Feb 3, 2017 at 16:47
- @Rewanth, yeah might also be part of the apparent bug we see here. There is something going wrong for sure. – frontend_dev Commented Feb 3, 2017 at 16:48
- @frontend_dev I have a solution but its not absolute. Try to add border to the div tag, change the border color to the background color, add padding. By doing so you will be pressing your div tag and its border gets mixed up in the background color, so if the user clicks slightly outside the radius then also only the touchstart event is fired instead of mouseover. Make sure that size of border equals to the maximum radius of touch(this is the bug). You can make advanced changes to this idea to overe this bug in your application. But I still encourage you to report this bug to chrome. – Rewanth Tammana Commented Feb 4, 2017 at 18:45
2 Answers
Reset to default 4 +50I'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 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
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.