简体   繁体   中英

Touch move getting stuck Ignored attempt to cancel a touchmove

I'm messing around with touch events on a touch slider and I keep getting the following error:

Ignored attempt to cancel a touchmove event with cancelable=false, for example because scrolling is in progress and cannot be interrupted.

I'm not sure what is causing this problem, I am new to working with touch events and can't seem to fix this problem.

Here is the code handling the touch event:

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));
}

You can find the actual slider here at this pen .

If you swipe through fast enough it will throw the error and sometimes get stuck in the middle of a swipe. Still can't wrap my head around why it is not working. Any help/insight would be greatly appreciated. Not sure what I am doing wrong.

我有这个问题,所有我必须做的就是从touchend return true ,警告消失了。

The event must be cancelable . Adding an if statement solves this issue.

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

In your code you should put it here:

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

Calling preventDefault on touchmove while you're actively scrolling is not working in Chrome. To prevent performance issues, you cannot interrupt a scroll.

Try to call preventDefault() from touchstart and everything should be ok.

I know this is an old post but I had a lot of issues trying to solve this and I finally did so I wanted to share.

My issue was that I was adding an event listener within the ontouchstart and removing it in the ontouchend functions - something like this

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

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

function handleTouchMove(e) {
  e.preventDefault();
}

For some reason adding it removing it like this was causing this issue of the event randomly not being cancelable. So to solve this I kept the listener active and toggled a boolean on whether or not it should prevent the event - something like this:

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;
}

I was actually using React so my solution involved setting state, but I've simplified it for a more generic solution. Hopefully this helps someone!

Please remove e.preventDefault() , because event.cancelable of touchmove is false . So you can't call this method.

If it is an image, you can just set 'touch-action' to none in css.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM