Как правильно реализовать отслеживание событий указателя - PullRequest
0 голосов
/ 06 февраля 2019

Я хочу реализовать жест, используя события указателя API.

Для начала я попытался сохранить все pointerId, которые активны для элемента, в массив.
Для этого я зарегистрировал прослушиватель события pointerdown для элемента иpointerup прослушиватель для всего документа, так что, если указатель перетаскивается из элемента, когда он активен, он все еще не регистрируется в массиве, когда указатель поднимается над поверхностью устройства и т. Д.

Ниже приведен пример, который показывает, что я пытаюсь выполнить:

var target = document.getElementById('target')

var activePointers = [];

target.addEventListener('pointerdown', function(event) {
  event.preventDefault();
  event.stopImmediatePropagation();

  // Add the pointerId to the array.
  activePointers.push(event.pointerId);
  target.textContent = activePointers;
});

// I realize that this document-wide listener should only be added once the 
// pointer is down, but that would add needless complexity to the example.
document.addEventListener('pointerup', function(event) {
  event.preventDefault();
  event.stopImmediatePropagation();

  // Remove the pointerId from the array.
  activePointers = activePointers.filter(item => item !== event.pointerId);
  target.textContent = activePointers;
});
#target {
  width: 400px;
  height: 150px;
  background: tomato;
  font-size: 4em;
  padding: .5em;
}
<!-- pointer events polyfill for mobile safari and firefox. -->
<script src="https://code.jquery.com/pep/0.4.3/pep.js"></script>

<div id="target" touch-action="none"></div>

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

Здесь есть несколько проблем, которые я не знаю, как их исправить.

  • pointerup не всегда срабатывает, в результате чего неактивные идентификаторы создаются в массиве.
  • Когда указатель немного перемещается, он ведет себя так, как если бы он был удален с поверхности, вызывая срабатывание pointerup.Этого нельзя обойти с помощью preventDefault() или stopImmediatePropagation().
  • При касании экрана несколькими указателями может открыться контекстное меню, даже если для события было вызвано preventDefault() или stopImmediatePropagation().
  • При перемещении указателя на элемент можно запустить прокрутку, даже если для события был вызван preventDefault().

Как правильно реализовать это, без вышеуказанных проблем?

РЕДАКТИРОВАТЬ0: Добавлен полифилл для Safari и Firefox Mobile.
РЕДАКТИРОВАТЬ1: Пример изображения нескольких указателей, которые все еще зарегистрированы, даже если на экране нет указателя:https://i.imgur.com/ggnSBNv.png
EDIT2: В iOS-Safari он работает так, как и ожидалось с использованием полифилла.
EDIT3: В Android-Chrome он работает должным образом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...