检测触摸设备上的左/右滑动,但允许向上/向下滚动

我需要检测并对左/右滑动作出反应,但是想让用户能够滚动相同的元素,所以只要他左右移动他的手指,最大上/下移动X像素,它不应该滚动,但是当它超过X时,它应该滚动。

所以我做的是:

var startX, startY, $this = $(this); function touchmove(event) { var touches = event.originalEvent.touches; if (touches && touches.length) { var deltaX = touches[0].pageX - startX; var deltaY = touches[0].pageY - startY; if (Math.abs(deltaY) > 50) { $this.html('X: ' + deltaX + '
Y: ' + deltaY + '
TRUE'); $this.unbind('touchmove', touchmove); return true; } else { $this.html('X: ' + deltaX + '
Y: ' + deltaY); event.preventDefault(); } } } function touchstart(event) { var touches = event.originalEvent.touches; if (touches && touches.length) { startX = touches[0].pageX; startY = touches[0].pageY; $this.bind('touchmove', touchmove); } //event.preventDefault(); }

但是我没有恢复滚动“if”情况的能力……

谢谢你的任何提示。

我写了自己的触摸处理程序events.maybe这可以帮助你

它检查:

快速点击:’fc’

向左滑动:’swl’

向右滑动:’swr’

向上滑动:’swu’

向下滑动:’swd’

每次检查都会初始化它的通讯事件。但是你可以滚动并做任何你正常做的事情。 你刚刚有一些新事件。

你需要swl swr,我建议使用fc(fastclick)进行点击事件……它比普通点击快得多。

 window.onload=function(){ (function(d){ var ce=function(e,n){var a=document.createEvent("CustomEvent");a.initCustomEvent(n,true,true,e.target);e.target.dispatchEvent(a);a=null;return false}, nm=true,sp={x:0,y:0},ep={x:0,y:0}, touch={ touchstart:function(e){sp={x:e.touches[0].pageX,y:e.touches[0].pageY}}, touchmove:function(e){nm=false;ep={x:e.touches[0].pageX,y:e.touches[0].pageY}}, touchend:function(e){if(nm){ce(e,'fc')}else{var x=ep.x-sp.x,xr=Math.abs(x),y=ep.y-sp.y,yr=Math.abs(y);if(Math.max(xr,yr)>20){ce(e,(xr>yr?(x<0?'swl':'swr'):(y<0?'swu':'swd')))}};nm=true}, touchcancel:function(e){nm=false} }; for(var a in touch){d.addEventListener(a,touch[a],false);} })(document); //EXAMPLE OF USE var h=function(e){console.log(e.type,e)}; document.body.addEventListener('fc',h,false);// 0-50ms vs 500ms with normal click document.body.addEventListener('swl',h,false); document.body.addEventListener('swr',h,false); document.body.addEventListener('swu',h,false); document.body.addEventListener('swd',h,false); } 

在这种情况下,h是我处理每种类型事件的处理程序,我将处理程序添加到正文中。

因为我理解你的问题,你只需要写

 YOURELEMENT.addEventListener('swr',YOURSWIPERIGHTFUNCTION,false); YOURELEMENT.addEventListener('swl',YOURSWIPELEFTFUNCTION,false); 

处理多个元素和相同的function...只需添加一个处理程序。

所以,如果你有

 
  • 1
  • 2
  • 3

你做:

 var deleteli=function(e){ var li=e.target; console.log('deleting '+li.textContent); } document.getElementById('ul').addEventListener('swl',deleteli,false); 

同样适用于fc&swr

ios中有一个错误:不要使用alert()..它会执行2次。

接受的答案中有一个“错误”。 如果您不在Android上使用Chrome,而是使用浏览器中的内置版本或“webview”(例如,对于html5-hybrid-app),则不会检测到滑动。

我发现事件不会触发,因为正常的滚动行为。 所以添加“e.preventDefault();” 在touchmove中会修复它或者Eric Fuller在接受的答案中修复它。

这是一个很好的剪辑,但在移动WebApp或网站中,这可能导致糟糕的滚动口吃,因为触摸事件是在整个时间观察。

所以我决定建立新的东西。 拥有新的事件听众并不是那么舒服,但它足以满足我的需求并且具有良好的性能。

 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 = 20; //min x swipe for horizontal swipe var max_x = 40; //max x difference for vertical swipe var min_y = 40; //min y swipe for vertical swipe var max_y = 50; //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)))) { if(swipe_det.eX > swipe_det.sX) direc = "r"; else direc = "l"; } //vertical detection 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)))) { if(swipe_det.eY > swipe_det.sY) direc = "d"; else direc = "u"; } if (direc != "") { if(typeof func == 'function') func(el,direc); } direc = ""; },false); } myfunction(el,d) { alert("you swiped on element with id '"+el+"' to "+d+" direction"); } 

要使用该function,请使用它

 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/

所有这些代码都需要改进(就像你在触摸操作中可以找到的大多数代码一样)。

在玩触摸事件时,请记住,用户有多个手指 ,触摸有标识符touches列表表示表面上的所有当前触摸,甚至触摸没有移动

所以这个过程比较简单:

  1. ontouchstart:获取第一个更改的触摸(不是event.originalEvent.touches属性,而是event.originalEvent.changedTouches一个)。 使用event.originalEvent.changedTouches[0].identifier和touch属性来注册其标识符( pageX / pageYclientX / clientY ,它们与DOMElement.getBoundingClientRect()方法结合使用非常有用);

  2. ontouchmove:使用event.originalEvent.changedTouches.identifiedTouch( identifier )确保当前触摸位于changedTouches列表中。 如果它什么也没有返回,那意味着用户已经移动了另一个触摸(而不是您正在寻找的那个)。 还可以注册触摸属性以查找并执行任何操作。

  3. ontouchend:再次,您必须确保当前触摸位于changedTouches列表中。 使用触摸属性完成工作,最后丢弃当前的触摸标识符。

如果你想做得更强,可以考虑多次接触(不仅仅是一次)来观察。

有关TouchEvent,TouchList和Touch的更多信息: https : //developer.mozilla.org/en-US/docs/Web/Guide/Events/Touch_events

触摸时左右检测仍在移动

这是通过保存最后位置并使用超时来擦除触摸停止后的最后位置来完成的。

 var currentX; var lastX = 0; var lastT; $(document).bind('touchmove', function(e) { // If still moving clear last setTimeout clearTimeout(lastT); currentX = e.originalEvent.touches[0].clientX; // After stoping or first moving if(lastX == 0) { lastX = currentX; } if(currentX < lastX) { // Left } else if(currentX > lastX){ // Right } // Save last position lastX = currentX; // Check if moving is done lastT = setTimeout(function() { lastX = 0; }, 100); });