4

I'm trying to build a simple prototype in which I want to capture whether a user is either entering or leaving the website on desktop. Through 2 strips and a onmouseover/onmouseout I want to understand whether it's an inbound or outbound case. Hence the expected outcome is to get to the following sequences:

  • Outbound sequence: MouseIn: lowerStrip - MouseOut: lowerStrip - MouseIn: upperStrip - MouseOut: upperStrip

  • Inbound sequence: MouseIn: upperStrip - MouseOut: upperStrip - MouseIn: lowerStrip - MouseOut: lowerStrip

Unfortunately, the sequence produced by my prototype is not always the same - sometimes the 4 lines are printed to the console, sometimes only 2, and sometimes not even a single one. Seems like others have struggled with this same issue, be it in different languages and different contexts:

How do you Hover in ReactJS? - onMouseLeave not registered during fast hover over

onMouseEnter and onMouseLeave not functioning as expected

Mouseout and mouseleave not working

mouseenter and mouseleave in javascript not working

Regardless of some insights gathered from these solutions, I couldn't figure out how to actually make my solution more robuust, especially because I couldn't understand the actual root cause of the issue. Some where talking about speed being the issue, but even when scrolling over quite slow, the issue occurs.

Hence I'd like to understand what is actually causing this behaviour and what the best solution is to resolve this e.g. is it an issue in JS and could it be resolved with JS, is it an issue in JS and should it be resolved by CSS, is it another issue, ...

I attached my example below. The idea is to hover over the two strips, either coming from the bottom or the top. This should trigger the sequence mentioned earlier.

Thanks for your input.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Template</title>

  <style>
  </style>

  <style>
  </style>

  <script type='text/javascript'>

  function init() {
    document.getElementById('upperStrip').setAttribute('style', 'position: absolute; margin: 0 !important; top: 0px; width: ' + window.innerWidth +'px; border: 5px solid #ff0000');
    document.getElementById('lowerStrip').setAttribute('style', 'position: absolute; margin: 0 !important; top: 10px; width: ' + window.innerWidth +'px; border: 5px solid #000000');
  }

 function onMouseIn(x) {
   console.log("MouseIn: ", x.id);
 }

 function onMouseOut(x) {
   console.log("MouseOut: ", x.id);
 }

  </script>

</head>
<body onload="init()">
<hr id='upperStrip' onmouseover="onMouseIn(this)" onmouseout="onMouseOut(this)">
<hr id='lowerStrip' onmouseover="onMouseIn(this)" onmouseout="onMouseOut(this)">

</body>
</html>

EDIT: 04/07/2020

Meanwhile I figured out the root cause:

"The mousemove event triggers when the mouse moves. But that doesn’t mean that every pixel leads to an event. The browser checks the mouse position from time to time. And if it notices changes then triggers the events. That means that if the visitor is moving the mouse very fast then some DOM-elements may be skipped." (https://javascript.info/mousemove-mouseover-mouseout-mouseenter-mouseleave)

intermediate elements (or some of them) may be skipped

"In case of fast mouse movements, intermediate elements may be ignored, but one thing we know for sure: if the pointer “officially” entered an element (mouseover event generated), then upon leaving it we always get mouseout."

Based on that, I'm now looking for a solution that is robust for my particular case. Waiting for the events seems an option, but I can also not wait 'too long' because I'm trying to register an exit intent. Also I need to at least be able to generate a onmouseover before even having a chance to capture the onmouseout.

I found a source which mentioned that: "Mouse does not report its position by every pixel it passes, there are 20ms intervals between reports. If you manage to cross your control within this interval, it will catch no mouse events at all."

Hence I should be able to capture the 4 events in ~80ms? The question is how...

user1098973
  • 334
  • 2
  • 9
  • If you want to know if the user has focused on something else outside your website, you should use onblur event on the window element – Saadi Toumi Fouad Apr 07 '20 at 17:30
  • 1
    @SaymoinSam not what I intend to achieve, please read my question more carefully... – user1098973 Apr 07 '20 at 20:51
  • Have you tried mouseIn/mouseOut on the body tag? – daotoad Apr 07 '20 at 22:59
  • Does this answer your question? [Why can't I reliably capture a mouseout event?](https://stackoverflow.com/questions/7448468/why-cant-i-reliably-capture-a-mouseout-event) – SRack Sep 29 '21 at 13:03

0 Answers0