如何检测用户用JavaScript在网页上向某个方向滑动手指?

我想知道是否有一种解决方案可以同时适用于iPhone和Android手机上的网站。


当前回答

我重新包装了TouchWipe作为一个简短的jquery插件:detectSwipe

其他回答

函数检查水平方向和垂直方向,以确定哪个滑动更长,以防止执行两个指令,因为不可能进行完美的单向滑动。滑动总是在X和Y上有偏差。

let touchstartX = 0;
let touchendX = 0;
let touchstartY = 0;
let touchendY = 0;   

function checkDirection() {
    let difX = touchstartX - touchendX;
    let difY = touchstartY - touchendY;
if (Math.abs(difX) > Math.abs(difY)) {
    if (touchendX < touchstartX) {/*left*/}
    if (touchendX > touchstartX) {/*right*/}
} else {
    if (touchendY < touchstartY) {/*up*/}
    if (touchendY > touchstartY) {/*down*/}
}
};
document.addEventListener('touchstart', e => {
    e.preventDefault();
    touchstartX = e.changedTouches[0].screenX;
    touchstartY = e.changedTouches[0].screenY;
});

document.addEventListener('touchend', e => {
    e.preventDefault();
    touchendX = e.changedTouches[0].screenX;
    touchendY = e.changedTouches[0].screenY;
    checkDirection();
});

我之前使用的方法是,您必须检测mousedown事件,记录其x,y位置(任何相关的位置),然后检测mouseup事件,并减去两个值。

jQuery Mobile还包括滑动支持:http://api.jquerymobile.com/swipe/

例子

$("#divId").on("swipe", function(event) {
    alert("It's a swipe!");
});

我也合并了一些答案,主要是第一个和第二个与类,下面是我的版本:

export default class Swipe {
    constructor(options) {
        this.xDown = null;
        this.yDown = null;

        this.options = options;

        this.handleTouchStart = this.handleTouchStart.bind(this);
        this.handleTouchMove = this.handleTouchMove.bind(this);

        document.addEventListener('touchstart', this.handleTouchStart, false);
        document.addEventListener('touchmove', this.handleTouchMove, false);

    }

    onLeft() {
        this.options.onLeft();
    }

    onRight() {
        this.options.onRight();
    }

    onUp() {
        this.options.onUp();
    }

    onDown() {
        this.options.onDown();
    }

    static getTouches(evt) {
        return evt.touches      // browser API

    }

    handleTouchStart(evt) {
        const firstTouch = Swipe.getTouches(evt)[0];
        this.xDown = firstTouch.clientX;
        this.yDown = firstTouch.clientY;
    }

    handleTouchMove(evt) {
        if ( ! this.xDown || ! this.yDown ) {
            return;
        }

        let xUp = evt.touches[0].clientX;
        let yUp = evt.touches[0].clientY;

        let xDiff = this.xDown - xUp;
        let yDiff = this.yDown - yUp;


        if ( Math.abs( xDiff ) > Math.abs( yDiff ) ) {/*most significant*/
            if ( xDiff > 0 && this.options.onLeft) {
                /* left swipe */
                this.onLeft();
            } else if (this.options.onRight) {
                /* right swipe */
                this.onRight();
            }
        } else {
            if ( yDiff > 0 && this.options.onUp) {
                /* up swipe */
                this.onUp();
            } else if (this.options.onDown){
                /* down swipe */
                this.onDown();
            }
        }

        /* reset values */
        this.xDown = null;
        this.yDown = null;
    }
}

之后可以这样使用:

let swiper = new Swipe({
                    onLeft() {
                        console.log('You swiped left.');
                    }
});

当你只想调用“onLeft”方法时,它有助于避免控制台错误。

touchStart和touchEnd的句柄:

var handleSwipe = function(elem,callbackOnRight, callbackOnLeft, callbackOnDown, 
      callbackOnUp) => {

        elem.ontouchstart = handleTouchStart;
        elem.ontouchend = handleTouchEnd;

        var xDown = null;
        var yDown = null;

        function getTouches(evt) {
            return evt.touches ||             // browser API
                evt.originalEvent.touches; // jQuery
        }

        function handleTouchStart(evt) {
            const firstTouch = getTouches(evt)[0];
            xDown = firstTouch.clientX;
            yDown = firstTouch.clientY;
        };

        function handleTouchEnd(evt) {
            if (!xDown || !yDown) {
                return;
            }

            var xUp = evt.changedTouches[0].clientX;
            var yUp = evt.changedTouches[0].clientY;

            var xDiff = xDown - xUp;
            var yDiff = yDown - yUp;
            var minDif = 30;

            console.log(`xDiff:${xDiff}, yDiff:${yDiff}`);

            if (Math.abs(xDiff) > Math.abs(yDiff)) {
                if (xDiff > minDif) {
                    if (callbackOnLeft)
                        callbackOnLeft();
                } else if (xDiff < -1 * minDif){
                    if (callbackOnRight)
                        callbackOnRight();
                }
            } else {
                if (yDiff > minDif) {
                    if (callbackOnDown)
                        callbackOnDown();
                } else if (yDiff < -1* minDif){
                    if (callbackOnUp)
                        callbackOnUp();
                }
            }
            
            xDown = null;
            yDown = null;
        };
    }