触摸移动卡住忽略尝试取消触摸移动

sou*_*ous 38 javascript jquery slider event-handling touch

我正在搞乱触摸滑块上的触摸事件,我不断收到以下错误:

忽略尝试取消具有cancelable = false的touchmove事件,例如因为滚动正在进行且无法中断.

我不确定是什么导致了这个问题,我不熟悉触摸事件,似乎无法解决这个问题.

以下是处理触摸事件的代码:

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));
}
Run Code Online (Sandbox Code Playgroud)

您可以在此笔中找到实际的滑块.

如果你快速滑动它会抛出错误,有时会卡在滑动中间.仍然无法解决为什么它不起作用.任何帮助/见解将不胜感激.不确定我做错了什么.

SrA*_*Axi 14

该活动必须是cancelable.添加if语句可以解决此问题.

if (e.cancelable) {
   e.preventDefault();
}
Run Code Online (Sandbox Code Playgroud)

在你的代码中你应该把它放在这里:

if (this.isSwipe(swipeThreshold) && e.cancelable) {
   e.preventDefault();
   e.stopPropagation();
   swiping = true;
}
Run Code Online (Sandbox Code Playgroud)


Che*_*het 11

我遇到了这个问题,所有我必须做的就是return true来自touchend并且警告消失了.

  • 这里没有任何改变 (9认同)
  • 在尝试在此语句中调用`e.preventDefault()`之前,我将`e.cancelable`添加到if语句中. (3认同)

Mar*_*ard 6

preventDefaulttouchmove您主动滚动时调用在Chrome中无法正常工作.为防止出现性能问题,您无法中断滚动.

尝试调用preventDefault()touchstart,一切都应该没问题.

  • 然后我得到:忽略尝试取消touchstart事件 (3认同)

Jef*_*dez 6

我知道这是一篇过时的文章,但是我有很多问题想要解决,我终于做到了,所以我想分享一下。

我的问题是我在ontouchstart中添加了事件侦听器,并在ontouchend函数中将其删除-像这样

function onTouchStart() {
  window.addEventListener("touchmove", handleTouchMove, {
    passive: false
  });
}

function onTouchEnd() {
  window.removeEventListener("touchmove", handleTouchMove, {
    passive: true
  });
}

function handleTouchMove(e) {
  e.preventDefault();
}
Run Code Online (Sandbox Code Playgroud)

由于某种原因,添加它会像这样删除它,导致此事件随机地无法取消。因此,为了解决此问题,我保持了侦听器处于活动状态,并在布尔值是否应该阻止该事件之间切换了一个布尔值,如下所示:

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;
}
Run Code Online (Sandbox Code Playgroud)

我实际上是在使用React,所以我的解决方案涉及设置状态,但是我将其简化为更通用的解决方案。希望这可以帮助某人!