Прикоснитесь к движению, застрявшему. Игнорируйте попытку отменить сенсорную кнопку
Я возился с событиями касания на сенсорном слайдере, и я продолжаю получать следующую ошибку:
Игнорированная попытка отменить событие touchmove с cancelable = false, например, поскольку выполняется прокрутка и не может быть прерываться.
Я не уверен, что вызывает эту проблему, я новичок в работе с событиями касания и не могу решить эту проблему.
Вот код, обрабатывающий событие касания:
Slider.prototype.isSwipe = function(threshold) {
return Math.abs(deltaX) > Math.max(threshold, Math.abs(deltaY));
}
Slider.prototype.touchStart = function(e) {
if (this._isSliding) return false;
touchMoving = true;
deltaX = deltaY = 0;
if (e.originalEvent.touches.length === 1) {
startX = e.originalEvent.touches[0].pageX;
startY = e.originalEvent.touches[0].pageY;
this._$slider.on('touchmove touchcancel', this.touchMove.bind(this)).one('touchend', this.touchEnd.bind(this));
isFlick = true;
window.setTimeout(function() {
isFlick = false;
}, flickTimeout);
}
}
Slider.prototype.touchMove = function(e) {
deltaX = startX - e.originalEvent.touches[0].pageX;
deltaY = startY - e.originalEvent.touches[0].pageY;
if(this.isSwipe(swipeThreshold)) {
e.preventDefault();
e.stopPropagation();
swiping = true;
}
if(swiping) {
this.slide(deltaX / this._sliderWidth, true)
}
}
Slider.prototype.touchEnd = function(e) {
var threshold = isFlick ? swipeThreshold : this._sliderWidth / 2;
if (this.isSwipe(threshold)) {
deltaX < 0 ? this.prev() : this.next();
}
else {
this.slide(0, !deltaX);
}
swiping = false;
this._$slider.off('touchmove', this.touchMove).one(transitionend, $.proxy(function() {
this.slide(0, true);
touchMoving = false;
}, this));
}
Вы можете найти фактический слайдер здесь, на этом пером.
Если вы проскользните достаточно быстро, это вызовет ошибку и иногда застрянет посреди салфетки. Все еще не могу окутать голову, почему она не работает. Любая помощь/понимание будут оценены. Не уверен, что я делаю неправильно.
Ответы
Ответ 1
Событие должно быть cancelable
. Добавление оператора if
решает эту проблему.
if (e.cancelable) {
e.preventDefault();
}
В вашем коде вы должны поместить его здесь:
if (this.isSwipe(swipeThreshold) && e.cancelable) {
e.preventDefault();
e.stopPropagation();
swiping = true;
}
Ответ 2
У меня была эта проблема, и все, что мне нужно было сделать, это return true
от touchhend, и предупреждение ушло.
Ответ 3
Вызов preventDefault
на touchmove
, пока вы активно прокручиваете, не работает в Chrome. Чтобы предотвратить проблемы с производительностью, вы не можете прервать прокрутку.
Попробуйте вызвать preventDefault()
из touchstart
, и все должно быть в порядке.
Ответ 4
Пожалуйста, удалите e.preventDefault()
, потому что event.cancelable
от touchmove имеет значение false
. Таким образом, вы не можете вызвать этот метод.
Ответ 5
Я знаю, что это старый пост, но у меня было много проблем, пытающихся решить эту проблему, и я наконец сделал это, поэтому я хотел поделиться.
Моя проблема заключалась в том, что я добавлял прослушиватель событий в ontouchstart и удалял его в функциях ontouchend - что-то вроде этого
function onTouchStart() {
window.addEventListener("touchmove", handleTouchMove, {
passive: false
});
}
function onTouchEnd() {
window.removeEventListener("touchmove", handleTouchMove, {
passive: true
});
}
function handleTouchMove(e) {
e.preventDefault();
}
По какой-то причине, добавив его, удалив его, как это, вызвало случайную невозможность отмены этого события. Поэтому, чтобы решить эту проблему, я оставил слушателя активным и переключил логическое значение на то, должно ли оно предотвращать событие - что-то вроде этого:
let stopScrolling = false;
window.addEventListener("touchmove", handleTouchMove, {
passive: false
});
function handleTouchMove(e) {
if (!stopScrolling) {
return;
}
e.preventDefault();
}
function onTouchStart() {
stopScrolling = true;
}
function onTouchEnd() {
stopScrolling = false;
}
На самом деле я использовал React, поэтому мое решение включало установку состояния, но я упростил его для более общего решения. Надеюсь, это кому-нибудь поможет!