mouseover иногда срабатывает вместо touchstart-почему?

Я нашел очень странное поведение, которое я не могу объяснить. Хотите сделать следующее:

обработчик должен реагировать на touchstart или mouseover событие, в зависимости от типа входного устройства. Обратите внимание, что я хочу поддерживать гибридные устройства (с мышью и сенсорным экраном), и я не могу полагаться на события указателя.

теперь, я просто настроить оба touchstart и mouseoverсобытий. И по большей части это работает просто отлично. Также используйте preventDefault запретить имитация события "мыши", срабатывающие после событий касания. Но что меня совершенно сбивает с толку, так это то, что иногда есть еще a mouseover событие происходит, и если я удаляю preventDefault, даже кажется, что mouseoverстреляет of a touchstart. Почему, почему это происходит?

кроме того, это воспроизводимо как с Android, так и с iOS! Хотя это, кажется, более легко запускается с Android (с помощью Chrome).

Я подготовил маленький тестовый кейс, чтобы вы могли попробовать сами. Обратите внимание, что это поведение запускается только при нажатии где-то на границе между красным DIV (который имеет события) и фоном. Просто нажатие в центре работает на 100%. И вам может понадобиться больше или меньше попыток, пока это не произойдет.

любая помощь очень ценится!

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

2 ответов


Я немного покопался в вашем примере, и это похоже на ошибку в Chrome. Я не мог воспроизвести его в Firefox. Вы можете воспроизвести его в инструменты разработчика Chrome на рабочем столе и на самом деле я нашел способ воспроизвести его в 100% случаев:

  • откройте инструменты dev и переключитесь в режим устройства
  • поместите курсор окружности на край красного прямоугольника так, чтобы центр курсора находился вне красного прямоугольника chrome dev tool cursor извините за качество изображения, я не удается захватить этот курсор с помощью скриншота
  • клик
  • для того, чтобы работать в следующий раз, вы должны сначала нажать на черном фоне красного прямоугольника

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


события мыши (mouseover, mouseout, mousedown, mouseup, mousemove и т. д.) относятся к устройству ввода мыши.

событие javascript mouseover преобразуется в события касания touchenter. Эти события являются частью проекта W3C (в настоящее время только поддержка Firefox), поэтому, если вы хотите его использовать, вы должны реализовать свою функцию onmouseover, используя событие touchmove и глядя на координаты и видеть, перекрываются ли они с координатами вашего html-элемента.

I думай, что это тебе поможет.