Détecter les glissades gauche / droite sur les appareils tactiles, mais autoriser le défilement vers le haut / vers le bas

J'ai besoin de détecter et de réagir aux glissades gauche / droite, mais je veux donner à l'utilisateur la possibilité de défiler sur le même élément, dans la mesure où il déplace son doigt seulement à gauche / droite avec un mouvement maximal vers le haut / bas de pixels X , Il ne doit pas se défiler, mais quand il dépasse X, il doit défiler.

Donc, ce que j'ai fait, c'est:

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 + '<br> Y: ' + deltaY + '<br>TRUE'); $this.unbind('touchmove', touchmove); return true; } else { $this.html('X: ' + deltaX + '<br> 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(); } 

Mais je ne rétablis pas la possibilité de défiler dans le cas "if" …

Merci pour tous les conseils.

J'ai écrit mes propres événements touchant le manipulateur tactile. Peut-être que cela vous aide

Il vérifie:

Clic rapide: 'fc'

Glisser à gauche: 'swl'

Glisser droit: 'swr'

Balayez: 'swu'

Glisser vers le bas: 'swd'

Chaque vérification initialise son événement correspondant. Mais vous pouvez faire défiler et faire tout ce que vous faites normalement. Vous avez juste de nouveaux événements.

Vous avez besoin swl swr, je suggère également d'utiliser fc (fastclick) pour les événements de clic … c'est beaucoup plus rapide que le clic normal.

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

Dans ce cas, h est mon gestionnaire pour chaque type d'événement et j'ajoute les gestionnaires au corps.

Pour ce que je comprends votre question, il vous suffit d'écrire

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

Pour gérer plusieurs éléments et la même fonction … ajoutez simplement un gestionnaire.

Donc si vous avez

 <ul id="ul"><li>1</li><li>2</li><li>3</li></ul> 

tu fais:

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

Même pour fc & swr

Il y a un bug dans ios: n'utilisez pas l'alerte () … il sera exécuté 2 fois.

Il y a un «bogue» dans la réponse acceptée. Si vous n'utilisez pas Chrome sur Android, mais la construction dans un navigateur ou une "vision du Web" (pour une application html5-hybride) par exemple, le coup de passe n'est pas détecté.

J'ai découvert que l'événement ne déclenche pas, en raison du comportement de défilement normal. En ajoutant "e.preventDefault ();" En touchmove le réparerait ou le correctif d'Eric Fuller dans la réponse acceptée.

C'est un joli coupé, mais dans un WebApp ou un site Web mobile, cela pourrait entraîner un mauvais balayage du défilement, car les événements tactiles sont observés tout le temps.

J'ai donc décidé de construire quelque chose de nouveau. Ce n'est pas aussi confortable que d'avoir de nouveaux auditeurs d'événements, mais c'est assez confortable pour mes besoins et c'est performat.

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

Pour utiliser la fonction, utilisez-la comme

 detectswipe('an_element_id',myfunction); detectswipe('an_other_element_id',my_other_function); 

Si un coup de fouet est détecté, la fonction "myfunction" est appelée avec element-id et "l, r, u, d" (gauche, droite, haut, bas).

Exemple: http://jsfiddle.net/rvuayqeo/1/

Tous ces codes doivent être améliorés (comme la plupart des codes que vous pouvez trouver sur la manipulation tactile).

Lorsque vous jouez avec un événement tactile, gardez à l'esprit que l'utilisateur dispose de plus d'un doigt , qu'un contact a un identifiant et qui touches liste représente toutes les touches actuelles sur la surface, même les touches qui n'ont pas bougé .

Le processus est donc relativement simple:

  1. Ontouchstart: obtenez la première touche modifiée (pas la propriété event.originalEvent.touches , mais event.originalEvent.changedTouches one). Enregistrez son identifiant avec event.originalEvent.changedTouches[0].identifier et touchez les propriétés à rechercher ( pageX / pageY ou clientX / clientY qui sont très utiles en combinaison avec la méthode DOMElement.getBoundingClientRect() );

  2. Ontouchmove: assurez-vous que le contact actuel se trouve dans la liste des event.originalEvent.changedTouches.identifiedTouch( identifier ) avec event.originalEvent.changedTouches.identifiedTouch( identifier ) . Si elle ne renvoie rien, cela signifie que l'utilisateur a déplacé une autre touche (pas celle que vous recherchez). Enregistrez également des propriétés tactiles pour rechercher et faire ce que vous voulez.

  3. Ontouchend: encore une fois, vous devez être sûr que la touche actuelle est changée. Faites le travail avec des propriétés tactiles et finalement jettez votre identifiant tactile actuel.

Si vous voulez le faire plus fort, pensez à plusieurs touches (pas seulement une) à observer.

Plus d'informations sur TouchEvent, TouchList et Touch on: https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Touch_events

Détecter la gauche et la droite tout en se déplaçant .

Cela se fait avec l'enregistrement de la dernière position et l'utilisation du délai d' expiration pour effacer la dernière position après l'arrêt du levier tactile.

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