在 iPhone 和 Android 上通过 JavaScript 检测手指滑动

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2264072/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 05:12:13  来源:igfitidea点击:

Detect a finger swipe through JavaScript on the iPhone and Android

javascriptiphoneandroidswipe

提问by 827

How can you detect that a user swiped his finger in some direction over a web page with JavaScript?

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

I was wondering if there was one solution that would work for websites on both the iPhone and an Android phone.

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

回答by givanse

Simple vanilla JS code sample:

简单的香草 JS 代码示例:

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

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 handleTouchMove(evt) {
    if ( ! xDown || ! yDown ) {
        return;
    }

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

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

    if ( Math.abs( xDiff ) > Math.abs( yDiff ) ) {/*most significant*/
        if ( xDiff > 0 ) {
            /* left swipe */ 
        } else {
            /* right swipe */
        }                       
    } else {
        if ( yDiff > 0 ) {
            /* up swipe */ 
        } else { 
            /* down swipe */
        }                                                                 
    }
    /* reset values */
    xDown = null;
    yDown = null;                                             
};

Tested in Android.

在安卓中测试。

回答by DaiLak

I found this jquery touchwipe plugin which works on both my first generation ipod touch and my droid incredible. http://www.netcu.de/jquery-touchwipe-iphone-ipad-library

我发现这个 jquery touchwipe 插件适用于我的第一代 ipod touch 和我的 droid 令人难以置信。 http://www.netcu.de/jquery-touchwipe-iphone-ipad-library

回答by Marwelln

Based on @givanse's answer, this is how you could do it with classes:

根据@givanse 的回答,您可以这样做classes

class Swipe {
    constructor(element) {
        this.xDown = null;
        this.yDown = null;
        this.element = typeof(element) === 'string' ? document.querySelector(element) : element;

        this.element.addEventListener('touchstart', function(evt) {
            this.xDown = evt.touches[0].clientX;
            this.yDown = evt.touches[0].clientY;
        }.bind(this), false);

    }

    onLeft(callback) {
        this.onLeft = callback;

        return this;
    }

    onRight(callback) {
        this.onRight = callback;

        return this;
    }

    onUp(callback) {
        this.onUp = callback;

        return this;
    }

    onDown(callback) {
        this.onDown = callback;

        return this;
    }

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

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

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

        if ( Math.abs( this.xDiff ) > Math.abs( this.yDiff ) ) { // Most significant.
            if ( this.xDiff > 0 ) {
                this.onLeft();
            } else {
                this.onRight();
            }
        } else {
            if ( this.yDiff > 0 ) {
                this.onUp();
            } else {
                this.onDown();
            }
        }

        // Reset values.
        this.xDown = null;
        this.yDown = null;
    }

    run() {
        this.element.addEventListener('touchmove', function(evt) {
            this.handleTouchMove(evt).bind(this);
        }.bind(this), false);
    }
}

You can than use it like this:

你可以像这样使用它:

// Use class to get element by string.
var swiper = new Swipe('#my-element');
swiper.onLeft(function() { alert('You swiped left.') });
swiper.run();

// Get the element yourself.
var swiper = new Swipe(document.getElementById('#my-element'));
swiper.onLeft(function() { alert('You swiped left.') });
swiper.run();

// One-liner.
(new Swipe('#my-element')).onLeft(function() { alert('You swiped left.') }).run();

回答by John Doherty

I merged a few of the answers here into a script that uses CustomEventto fire swiped events in the DOM. Add the 0.7k swiped-events.min.jsscript to your page and listen for swipedevents:

我将这里的一些答案合并到一个脚本中,该脚本使用CustomEvent在 DOM 中触发滑动事件。在0.7K添加刷卡,events.min.js脚本到你的页面和监听刷卡事件:

swiped-left

向左滑动

document.addEventListener('swiped-left', function(e) {
    console.log(e.target); // the element that was swiped
});

swiped-right

向右滑动

document.addEventListener('swiped-right', function(e) {
    console.log(e.target); // the element that was swiped
});

swiped-up

向上滑动

document.addEventListener('swiped-up', function(e) {
    console.log(e.target); // the element that was swiped
});

swiped-down

向下滑动

document.addEventListener('swiped-down', function(e) {
    console.log(e.target); // the element that was swiped
});

You can also attach directly to an element:

您还可以直接附加到元素:

document.getElementById('myBox').addEventListener('swiped-down', function(e) {
    console.log(e.target); // the element that was swiped
});

Optional config

可选配置

You can specify the following attributes to tweak how swipe interaction functions in your page (these are optional).

您可以指定以下属性来调整页面中的滑动交互功能(这些是可选的)

<div data-swipe-threshold="10"
     data-swipe-timeout="1000"
     data-swipe-ignore="false">
        Swiper, get swiping!
</div>

Source code is available on Github

源代码可在Github 上找到

回答by Jorik

Have you tried hammer.js? http://eightmedia.github.com/hammer.js/Also works on Windows Phones..

你有没有尝试过hammer.js?http://eightmedia.github.com/hammer.js/也适用于 Windows Phones..

回答by Grinn

jQuery Mobile also includes swipe support: http://api.jquerymobile.com/swipe/

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

Example

例子

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

回答by helloandre

what i've used before is you have to detect the mousedown event, record its x,y location (whichever is relevant) then detect the mouseup event, and subtract the two values.

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

回答by nashcheez

I have found @givanse brilliant answer to be the most reliable and compatible across multiple mobile browsers for registering swipe actions.

我发现@givanse 出色的答案是在多个移动浏览器中最可靠和兼容的,用于注册滑动操作。

However, there's a change in his code required to make it work in modern day mobile browsers that are using jQuery.

但是,为了使其在使用jQuery.

event.toucheswon't exist if jQueryis used and results in undefinedand should be replaced by event.originalEvent.touches. Without jQuery, event.touchesshould work fine.

event.touches将不存在 ifjQuery被使用并导致undefined并且应该被替换为event.originalEvent.touches. 没有jQueryevent.touches应该可以正常工作。

So the solution becomes,

所以解决方案变成,

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

var xDown = null;                                                        
var yDown = null;                                                        

function handleTouchStart(evt) {                                         
    xDown = evt.originalEvent.touches[0].clientX;                                      
    yDown = evt.originalEvent.touches[0].clientY;                                      
};                                                

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

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

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

    if ( Math.abs( xDiff ) > Math.abs( yDiff ) ) {/*most significant*/
        if ( xDiff > 0 ) {
            /* left swipe */ 
        } else {
            /* right swipe */
        }                       
    } else {
        if ( yDiff > 0 ) {
            /* up swipe */ 
        } else { 
            /* down swipe */
        }                                                                 
    }
    /* reset values */
    xDown = null;
    yDown = null;                                             
};

Tested on:

测试:

  • Android: Chrome, UC Browser
  • iOS: Safari, Chrome, UC Browser
  • 安卓:Chrome、UC浏览器
  • iOS:Safari、Chrome、UC 浏览器

回答by Sergey Guns

trashold, timeout swipe, swipeBlockElems add.

垃圾桶,超时滑动,swipeBlockElems 添加。

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

const SWIPE_BLOCK_ELEMS = [
  'swipBlock',
  'handle',
  'drag-ruble'
]

let xDown = null;
let yDown = null; 
let xDiff = null;
let yDiff = null;
let timeDown = null;
const  TIME_TRASHOLD = 200;
const  DIFF_TRASHOLD = 130;

function handleTouchEnd() {

let timeDiff = Date.now() - timeDown; 
if (Math.abs(xDiff) > Math.abs(yDiff)) { /*most significant*/
  if (Math.abs(xDiff) > DIFF_TRASHOLD && timeDiff < TIME_TRASHOLD) {
    if (xDiff > 0) {
      // console.log(xDiff, TIME_TRASHOLD, DIFF_TRASHOLD)
      SWIPE_LEFT(LEFT) /* left swipe */
    } else {
      // console.log(xDiff)
      SWIPE_RIGHT(RIGHT) /* right swipe */
    }
  } else {
    console.log('swipeX trashhold')
  }
} else {
  if (Math.abs(yDiff) > DIFF_TRASHOLD && timeDiff < TIME_TRASHOLD) {
    if (yDiff > 0) {
      /* up swipe */
    } else {
      /* down swipe */
    }
  } else {
    console.log('swipeY trashhold')
  }
 }
 /* reset values */
 xDown = null;
 yDown = null;
 timeDown = null; 
}
function containsClassName (evntarget , classArr) {
 for (var i = classArr.length - 1; i >= 0; i--) {
   if( evntarget.classList.contains(classArr[i]) ) {
      return true;
    }
  }
}
function handleTouchStart(evt) {
  let touchStartTarget = evt.target;
  if( containsClassName(touchStartTarget, SWIPE_BLOCK_ELEMS) ) {
    return;
  }
  timeDown = Date.now()
  xDown = evt.touches[0].clientX;
  yDown = evt.touches[0].clientY;
  xDiff = 0;
  yDiff = 0;

}

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

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


  xDiff = xDown - xUp;
  yDiff = yDown - yUp;
}

回答by Marc-André Lafortune

I've repackaged TouchWipeas a short jquery plugin: detectSwipe

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