iOS6 JavaScript touchmove event pass through verti

2019-07-18 17:06发布

I have a div with a javascript touchmove event listener that scrolls the image inside the div horizontally on iOS6 Mobile Safari. I'd like allow vertical scrolling of the page to bubble up to the browser but when this occurs, jQuery.animate no longer works.

I've posted a simplified version of the code that demonstrates the problem at https://gist.github.com/4047733

The steps I take to recreate the problem are:

  • Swipe picture left/right and notice how it animates back to the left edge
  • Touch the picture and scroll the page up/down
  • Repeat left/right swipe and notice the picture does NOT animate back to the left edge. It appears jQuery animate fails after touchmove occurs without e.preventDefault

Here is the javascript inside jQuery document ready from the gist link above

var el = document.getElementById("swipebox"),
    $slider = $('#swipebox').find('img'),
    startX, startY, dx, dy,
    startLeft,
    animateH = false,
    animateV = false;

var onTouchStart = function(e) {
    startLeft = parseInt($slider.css('left'), 10) || 0;
    startX = e.touches[0].pageX;
    startY = e.touches[0].pageY;

};
var onTouchMove = function(e) {
    dx = e.touches[0].pageX - startX;
    dy = e.touches[0].pageY - startY;

    if (
        animateH || 
        (!animateV && Math.abs(dx) > 5) 
    ) {
        // prevent default, we are scrolling horizontally, 
        animateH = true;
        $slider.stop().css({'left': startLeft+dx*2});
        e.preventDefault();
    } else if (Math.abs(dy) > 5) {
        // do NOT prevent default, we are scrolling the page vertically
        animateV = true;
    } else {
        // direction of scroll is undetermined at this time
        // we've moved less than 5px in any direction
        e.preventDefault();
    }
    return false;
};
var onTouchEnd = function(e) {
    $slider.stop().animate({'left': 0}); // animate image back to left
    e.preventDefault();
    animateH = false;
    animateV = false;
};

var onTouchCancel = function(e) {
    console.log('onTouchCancel');
};

el.addEventListener('touchstart', onTouchStart, false);
el.addEventListener('touchmove', onTouchMove, false);
el.addEventListener('touchend', onTouchEnd, false);
el.addEventListener("touchcancel", onTouchCancel, false);

Any insight would be greatly appreciated.

1条回答
狗以群分
2楼-- · 2019-07-18 17:32

This is bug in iOS6. jQuery animate timers fail when scrolling window in iOS6. Currently there are few workarounds on this:

  1. Create your own timer functions like someone did: https://gist.github.com/3755461
  2. Use CSS3 transition instead of jQuery.animate. This is preffered way - css3 transitions doesn't have such problem. You can use this jquery plugin http://ricostacruz.com/jquery.transit/ to easily manipulate CSS transitions in JavaScript.
查看更多
登录 后发表回答