Я хочу реализовать жест, используя события указателя 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 он работает должным образом.