Ненадежная комбинация OnMouseOver / OnMouseOut - что на самом деле является причиной этого и как его лучше решить? - PullRequest
1 голос
/ 07 апреля 2020

Я пытаюсь создать простой прототип, в котором я хочу определить, входит ли пользователь на рабочий стол или покидает его. Через 2 полосы и onmouseover / onmouseout я хочу понять, является ли это входящий или исходящий случай. Следовательно, ожидаемый результат состоит в следующем:

  • Исходящая последовательность: MouseIn: lowerStrip - MouseOut: lowerStrip - MouseIn: upperStrip - MouseOut: upperStrip

  • Входящая последовательность: MouseIn: upperStrip - MouseOut: upperStrip - MouseIn: lowerStrip - MouseOut: lowerStrip

К сожалению, последовательность, созданная моим прототипом, не всегда одинакова - иногда 4 строки выводятся на консоль, иногда только 2, а иногда даже не одна. Похоже, что другие боролись с этой же проблемой, будь то на разных языках и в разных контекстах:

Как вы зависаете в ReactJS? - onMouseLeave не зарегистрирован во время быстрого наведения на

onMouseEnter и onMouseLeave не работают должным образом

Mouseout и Mouseleave не работают

mouseenter и mouseleave в javascript не работают

Независимо от некоторых идей, полученных из этих решений, я не мог понять, как на самом деле сделать мое решение более надежным, особенно потому, что Я не мог понять фактическую root причину проблемы . В некоторых случаях речь идет о скорости, но даже при довольно медленной прокрутке проблема возникает.

Следовательно, Я бы хотел понять, что на самом деле вызывает такое поведение и как лучше всего решить эту проблему Например, это проблема в JS и может ли она быть решена с помощью JS, это проблема в JS и должна ли она быть решена CSS, это еще одна проблема, ...

Я приложил свой пример ниже. Идея состоит в том, чтобы парить над двумя полосами, идущими снизу или сверху. Это должно вызвать последовательность, упомянутую ранее.

Спасибо за ваш ввод.

<!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>

РЕДАКТИРОВАТЬ: 04/07/2020

Тем временем я выяснил root причину :

"Событие mousemove срабатывает, когда мышь движется. Но это не значит, что каждый пиксель приводит к событию. Браузер время от времени проверяет положение мыши. И если он замечает изменения, то запускает события Это означает, что если посетитель очень быстро перемещает мышь, то некоторые DOM-элементы могут быть пропущены ». (https://javascript.info/mousemove-mouseover-mouseout-mouseenter-mouseleave)

intermediate elements (or some of them) may be skipped

"В случае быстрых движений мыши промежуточные элементы могут игнорироваться, но одно мы Знайте наверняка: если указатель «официально» введен в элемент (сгенерировано событие mouseover), то при выходе из него мы всегда получаем mouseout. "

Исходя из этого, я сейчас ищу надежное решение для моего конкретного случая. Ожидание событий кажется возможным, но я также не могу ждать «слишком долго», потому что я пытаюсь зарегистрировать намерение выхода. Кроме того, мне нужно, по крайней мере, иметь возможность сгенерировать onmouseover, прежде чем я смогу получить onmouseout

Я нашел источник, который упомянул, что: «Мышь не сообщает свое положение по каждому пикселю, который она проходит, интервалы между отчетами составляют 20 мс. Если вам удастся пересечь свой контроль в этом интервале, она не поймает мышь события на всех. "

Следовательно, я должен быть в состоянии захватить 4 события в ~ 80 мс? Вопрос в том, как ...

...