如何为移动设备实现滑动手势?

fot*_*lab 44 javascript mobile touch gestures swipe

我在AngularJS中有一个应用程序,它有箭头键导航来切换视图.

我想使用滑动触摸设备来实现此导航.我尝试过jGestures库,但刷卡效果不佳.我被建议不要使用jquery mobile.

有没有其他方法来实现滑动?

编辑:它没有检测到干净的滑动.我在多个设备上测试了它,包括iPad,需要多次滑动才能执行操作(在我的情况下路由).

Esc*_*ape 59

我根据自己的需要制作了这个功能.

随意使用它.适用于移动设备.

function detectswipe(el,func) {
  swipe_det = new Object();
  swipe_det.sX = 0; swipe_det.sY = 0; swipe_det.eX = 0; swipe_det.eY = 0;
  var min_x = 30;  //min x swipe for horizontal swipe
  var max_x = 30;  //max x difference for vertical swipe
  var min_y = 50;  //min y swipe for vertical swipe
  var max_y = 60;  //max y difference for horizontal swipe
  var direc = "";
  ele = document.getElementById(el);
  ele.addEventListener('touchstart',function(e){
    var t = e.touches[0];
    swipe_det.sX = t.screenX; 
    swipe_det.sY = t.screenY;
  },false);
  ele.addEventListener('touchmove',function(e){
    e.preventDefault();
    var t = e.touches[0];
    swipe_det.eX = t.screenX; 
    swipe_det.eY = t.screenY;    
  },false);
  ele.addEventListener('touchend',function(e){
    //horizontal detection
    if ((((swipe_det.eX - min_x > swipe_det.sX) || (swipe_det.eX + min_x < swipe_det.sX)) && ((swipe_det.eY < swipe_det.sY + max_y) && (swipe_det.sY > swipe_det.eY - max_y) && (swipe_det.eX > 0)))) {
      if(swipe_det.eX > swipe_det.sX) direc = "r";
      else direc = "l";
    }
    //vertical detection
    else if ((((swipe_det.eY - min_y > swipe_det.sY) || (swipe_det.eY + min_y < swipe_det.sY)) && ((swipe_det.eX < swipe_det.sX + max_x) && (swipe_det.sX > swipe_det.eX - max_x) && (swipe_det.eY > 0)))) {
      if(swipe_det.eY > swipe_det.sY) direc = "d";
      else direc = "u";
    }

    if (direc != "") {
      if(typeof func == 'function') func(el,direc);
    }
    direc = "";
    swipe_det.sX = 0; swipe_det.sY = 0; swipe_det.eX = 0; swipe_det.eY = 0;
  },false);  
}

function myfunction(el,d) {
  alert("you swiped on element with id '"+el+"' to "+d+" direction");
}
Run Code Online (Sandbox Code Playgroud)

要使用该功能,请使用它

detectswipe('an_element_id',myfunction);

detectswipe('an_other_element_id',my_other_function);
Run Code Online (Sandbox Code Playgroud)

如果检测到滑动,则使用参数element-id和"l,r,u,d"(左,右,上,下)调用函数"myfunction".

示例:http://jsfiddle.net/rvuayqeo/1/

  • 我已经对脚本,javascript 1.8和一些逻辑更改进行了一些更新.例如,如果使用增量,则不需要min_x,max_x,min_y和max_y.通过比较增量(`abs((eX - sX)/(eY - sY)`),在垂直和水平之间进行选择会更精确.你可以看到我的叉[这里](https://jsfiddle.net/ c8dq01Lw/6 /).如果这个评论得到足够的upvotes(比如5)我会编辑答案. (7认同)
  • @EscapeNetscape我喜欢你的滑动检测解决方案.但它错误地将单击和双击识别为滑动.我该如何解决这个问题? (3认同)

Jor*_*rik 26

你试过Hammerjs吗?它通过使用触摸的速度支持滑动手势. http://eightmedia.github.com/hammer.js/


Pix*_*omo 11

我发现最简单的解决方案不需要插件:

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 ) ) {/*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;                                             
};
Run Code Online (Sandbox Code Playgroud)


vsp*_*vsp 9

还有一个名为angular-gestures的AngularJS模块,它基于hammer.js:https: //github.com/wzr1337/angular-gestures


Ben*_*enM 6

我知道无耻的插件,但您可能想要考虑我写的jQuery插件:

https://github.com/benmajor/jQuery-Mobile-Events

它不需要jQuery Mobile,只需要jQuery.


Uly*_* BN 6

注意:受到EscapeNetscape 回答的极大启发,我在评论中使用现代 javascript 对他的脚本进行了编辑。由于用户的兴趣和大量的 4 小时 jsfiddle.net 停机时间,我对此做出了回答。我选择不编辑原始答案,因为它会改变一切......


这是一个detectSwipe功能,运行良好(在我的一个网站上使用)。我建议你在使用之前阅读它。随意查看/编辑答案。

// usage example
detectSwipe('swipeme', (el, dir) => alert(`you swiped on element with id ${el.id} to ${dir} direction`))

// source code

// Tune deltaMin according to your needs. Near 0 it will almost
// always trigger, with a big value it can never trigger.
function detectSwipe(id, func, deltaMin = 90) {
  const swipe_det = {
    sX: 0,
    sY: 0,
    eX: 0,
    eY: 0
  }
  // Directions enumeration
  const directions = Object.freeze({
    UP: 'up',
    DOWN: 'down',
    RIGHT: 'right',
    LEFT: 'left'
  })
  let direction = null
  const el = document.getElementById(id)
  el.addEventListener('touchstart', function(e) {
    const t = e.touches[0]
    swipe_det.sX = t.screenX
    swipe_det.sY = t.screenY
  }, false)
  el.addEventListener('touchmove', function(e) {
    // Prevent default will stop user from scrolling, use with care
    // e.preventDefault();
    const t = e.touches[0]
    swipe_det.eX = t.screenX
    swipe_det.eY = t.screenY
  }, false)
  el.addEventListener('touchend', function(e) {
    const deltaX = swipe_det.eX - swipe_det.sX
    const deltaY = swipe_det.eY - swipe_det.sY
    // Min swipe distance, you could use absolute value rather
    // than square. It just felt better for personnal use
    if (deltaX ** 2 + deltaY ** 2 < deltaMin ** 2) return
    // horizontal
    if (deltaY === 0 || Math.abs(deltaX / deltaY) > 1)
      direction = deltaX > 0 ? directions.RIGHT : directions.LEFT
    else // vertical
      direction = deltaY > 0 ? directions.UP : directions.DOWN

    if (direction && typeof func === 'function') func(el, direction)

    direction = null
  }, false)
}
Run Code Online (Sandbox Code Playgroud)
#swipeme {
  width: 100%;
  height: 100%;
  background-color: orange;
  color: black;
  text-align: center;
  padding-top: 20%;
  padding-bottom: 20%;
}
Run Code Online (Sandbox Code Playgroud)
<div id='swipeme'>
  swipe me
</div>
Run Code Online (Sandbox Code Playgroud)