简体   繁体   中英

Handling swipe in touch devices

I have this horizontal carousel component that I want to make it work for both Mouse and Swipe events. Everything is working fine, except for one bit: in touch devices, I don't want the carousel to scroll horizontally if the user is trying to swipe vertically to scroll through the whole page.

What I am doing is,

  • on mousedown/touchstart - I stop the event from propagating to avoid page scroll, item selects, etc...
  • on the first move event, on the carousel, I set a 50ms timeout to determine if the user is moving vertically or horizontally.
  • If deltaX < deltaY , I stop my horizontal scrolling, manually fire the touchstart event, with a flag indicating that i fired it manually
  • on my mousedown / touchstart handler, I read that "manually" flag and, if it's true, I return true from my function so all the default browser events, like the page vertical scrolling, continue to work.

This is not working, everything I'm doing responds correctly but the browser doesn't pick up and scroll the page. I hope I am explaining myself correctly enough so you guys can help me... I don't have an online example because this is a "secret" project for my company...

I was trying to do the same thing as you (were?). The key is to check on touchmove if the current touch and the last touch is more vertical than horizontal. If the touch was more left to right or right to left, prevent the event's default, otherwise ignore it. Here's what I ended up writing. Hopefully it works for you!

var gestures = function() {
    var self = this,
    coords = {
        startX: null,
        startY: null,
        endX: null,
        endY: null
    };

    self.$el.on('touchstart', function(e) {
        coords.startX = e.originalEvent.targetTouches[0].clientX;
        coords.startY = e.originalEvent.targetTouches[0].clientY;
        coords.endX = coords.startX;
        coords.endY = coords.startY;
    });

    self.$el.on('touchmove', function(e) {
        var newX = e.originalEvent.targetTouches[0].clientX,
            newY = e.originalEvent.targetTouches[0].clientY,
            absX = Math.abs(coords.endX - newX),
            absY = Math.abs(coords.endY - newY);

        // If we've moved more Y than X, we're scrolling vertically
        if (absX < absY) {
            return;
        }

        // Prevents the page from scrolling left/right
        e.preventDefault();

        coords.endX = newX;
        coords.endY = newY;
    });

    self.$el.on('touchend', function(e) {
        var swipe = {},
            deltaX = coords.startX - coords.endX,
            deltaY = coords.startY - coords.endY,
            absX = Math.abs(deltaX),
            absY = Math.abs(deltaY);

        swipe.distance = (absX > absY) ? absX : absY;
        swipe.direction = (absX < absY) ?
            (deltaY < 0 ? 'down' : 'up') :
            (deltaX < 0 ? 'right' : 'left');

        // console.log(swipe.direction + ' ' + swipe.distance + 'px');

        // If we have a swipe of > 50px, let's use it!
        if (swipe.distance > 50) {
            if (swipe.direction === 'left') {
                self.advance();
            } else if (swipe.direction === 'right') {
                self.retreat();
            }
        }

    });
};

this is my slider object and $el is the container element.

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