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

新手上路,请多包涵

我正在处理触摸滑块上的触摸事件,并且不断收到以下错误:

忽略取消带有 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));
}

您可以 在这支笔 上找到实际的滑块。

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

原文由 souporserious 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 643
2 个回答

该事件必须是 cancelable 。添加 if 语句可解决此问题。

 if (e.cancelable) {
   e.preventDefault();
}

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

 if (this.isSwipe(swipeThreshold) && e.cancelable) {
   e.preventDefault();
   e.stopPropagation();
   swiping = true;
}

原文由 SrAxi 发布,翻译遵循 CC BY-SA 4.0 许可协议

我知道这是一篇旧帖子,但我在尝试解决这个问题时遇到了很多问题,我终于做到了,所以我想分享。

我的问题是我在 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,所以我的解决方案涉及设置状态,但我已将其简化为更通用的解决方案。希望这对某人有帮助!

原文由 Jeff Hernandez 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏