如何检测用户使用JavaScript在网页上向某个方向滑动手指?
我想知道是否有一个解决方案适用于iPhone和Android手机上的网站.
简单的vanilla 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; };
在Android中测试过.
我发现这个jquery touchwipe插件适用于我的第一代ipod touch和我的droid令人难以置信. http://www.netcu.de/jquery-touchwipe-iphone-ipad-library
基于@ 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); } }
你可以像这样使用它:
// 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();
你试过hammer.js吗?http://eightmedia.github.com/hammer.js/ 也适用于Windows手机..
之前我用过的是你必须检测mousedown事件,记录它的x,y位置(以相关者为准)然后检测mouseup事件,然后减去这两个值.
jQuery Mobile还包括滑动支持:http://api.jquerymobile.com/swipe/
例
$("#divId").on("swipe", function(event) { alert("It's a swipe!"); });
我将这里的一些答案合并到一个脚本中,该脚本使用CustomEvent来触发DOM中的滑动事件.将0.7k pure-swipe.min.js脚本添加到您的页面并侦听滑动事件:
document.addEventListener('swiped-left', function(e) { console.log(e.target); // the element that was swiped });
document.addEventListener('swiped-right', function(e) { console.log(e.target); // the element that was swiped });
document.addEventListener('swiped-up', function(e) { console.log(e.target); // the element that was swiped });
document.addEventListener('swiped-down', function(e) { console.log(e.target); // the element that was swiped });
您还可以直接附加到元素:
document.getElementById('myBox').addEventListener('swiped-down', function(e) { console.log(e.target); // the element that was swiped });
您可以指定以下属性来调整页面中滑动交互功能的方式(这些是可选的).
Swiper, get swiping!
源代码可在Github上找到
我发现@givanse很棒的答案是在多个移动浏览器中最可靠和最兼容的注册滑动操作.
但是,他的代码需要更改才能使其在现代移动浏览器中使用jQuery
.
event.touches
如果jQuery
使用并且导致undefined
并且应该替换为将不存在event.originalEvent.touches
.没有jQuery
,event.touches
应该工作正常.
所以解决方案变成,
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; };
测试:
Android:Chrome,UC浏览器
iOS:Safari,Chrome,UC浏览器
我重新打包TouchWipe
为一个简短的jquery插件:detectSwipe
一些最新的答案(无法评论......)来处理短暂的滑动
document.addEventListener('touchstart', handleTouchStart, false); document.addEventListener('touchmove', handleTouchMove, false); var xDown = null; var yDown = null; function handleTouchStart(evt) { xDown = evt.touches[0].clientX; yDown = evt.touches[0].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 )>150){ //to deal with to short swipes if ( Math.abs( xDiff ) > Math.abs( yDiff ) ) {/*most significant*/ if ( xDiff > 0 ) {/* left swipe */ alert('left!'); } else {/* right swipe */ alert('right!'); } } else { if ( yDiff > 0 ) {/* up swipe */ alert('Up!'); } else { /* down swipe */ alert('Down!'); } } /* reset values */ xDown = null; yDown = null; } };
trashold,超时滑动,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; }