49

我有一个用 AngularJS 制作的应用程序,它有箭头键导航来切换视图。

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

还有其他方法可以实现滑动吗?

编辑:它不会干净地检测到滑动。我在包括 iPad 在内的多种设备上对其进行了测试,并且需要多次滑动才能执行操作(在我的情况下是路由)。

4

8 回答 8

67

我为我的需要制作了这个功能。

随意使用它。在移动设备上运行良好。

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");
}

要使用该功能,只需像这样使用它

detectswipe('an_element_id',myfunction);

detectswipe('an_other_element_id',my_other_function);

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

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


我(UlysseBN)基于这个脚本制作了一个新版本的脚本,它使用了更现代的 JavaScript,看起来它在某些情况下表现得更好。如果您认为应该编辑此答案,请告诉我,如果您是原作者并且最终进行了编辑,我将删除我的答案。

于 2014-11-24T22:06:42.877 回答
29

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

于 2013-02-28T11:53:06.667 回答
8

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

于 2013-06-14T12:19:47.763 回答
6

我知道无耻的插件,但你可能想考虑我写的一个 jQuery 插件:

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

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

于 2013-02-26T08:45:38.930 回答
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)
}
#swipeme {
  width: 100%;
  height: 100%;
  background-color: orange;
  color: black;
  text-align: center;
  padding-top: 20%;
  padding-bottom: 20%;
}
<div id='swipeme'>
  swipe me
</div>

于 2019-11-05T20:50:55.970 回答
2

我喜欢您的解决方案并在我的网站上实施了它 - 但是,有一些小的改进。只是想分享我的代码:

function detectSwipe(id, f) {
    var detect = {
        startX: 0,
        startY: 0,
        endX: 0,
        endY: 0,
        minX: 30,   // min X swipe for horizontal swipe
        maxX: 30,   // max X difference for vertical swipe
        minY: 50,   // min Y swipe for vertial swipe
        maxY: 60    // max Y difference for horizontal swipe
    },
        direction = null,
        element = document.getElementById(id);

    element.addEventListener('touchstart', function (event) {
        var touch = event.touches[0];
        detect.startX = touch.screenX;
        detect.startY = touch.screenY;
    });

    element.addEventListener('touchmove', function (event) {
        event.preventDefault();
        var touch = event.touches[0];
        detect.endX = touch.screenX;
        detect.endY = touch.screenY;
    });

    element.addEventListener('touchend', function (event) {
        if (
            // Horizontal move.
            (Math.abs(detect.endX - detect.startX) > detect.minX)
                && (Math.abs(detect.endY - detect.startY) < detect.maxY)
        ) {
            direction = (detect.endX > detect.startX) ? 'right' : 'left';
        } else if (
            // Vertical move.
            (Math.abs(detect.endY - detect.startY) > detect.minY)
                && (Math.abs(detect.endX - detect.startX) < detect.maxX)
        ) {
            direction = (detect.endY > detect.startY) ? 'down' : 'up';
        }

        if ((direction !== null) && (typeof f === 'function')) {
            f(element, direction);
        }
    });
}

像这样使用它:

detectSwipe('an_element_id', myfunction);

或者

detectSwipe('another_element_id', my_other_function);

如果检测到滑动,则myfunction使用参数 element-id 和'left', 'right', 'up'oder调用函数'down'

于 2018-02-04T13:26:31.553 回答
2

锤子时间!

我使用过 Hammer JS,它与手势配合使用。从这里阅读详细信息:https ://hammerjs.github.io/

好在它比 jQuery mobile 更轻、更快速。您也可以在他们的网站上进行测试。

于 2017-08-18T07:40:44.877 回答
0

我查看了几种解决方案,但都失败了,滚动和选择文本是最大的困惑。我没有向右滚动,而是关闭了盒子等。

我刚刚完成了为我完成所有工作的实现。

https://github.com/webdevelopers-eu/jquery-dna-gestures

它是麻省理工学院,所以做你想做的事——是的,它真的很简单——缩小了 800 字节。您可以在我的(开发中的)网站https://cyrex.tech上查看它- 在触摸设备上向右滑动应该会关闭弹出窗口。

于 2020-02-04T21:57:44.387 回答