web-dev-qa-db-fra.com

Déterminer la direction verticale d'un mouvement tactile

j'essaie d'implémenter un écouteur tactile pour les tablettes pour déclencher certaines actions selon qu'il est déplacé vers le haut ou vers le bas.

J'ai essayé l'auditeur natif:

($document).bind('touchmove', function (e)
{
    alert("it worked but i don't know the direction");
});

Mais je ne sais pas comment déterminer la direction.

Est-ce possible?

Ou dois-je utiliser Touchstart/Touchend, si j'en ai besoin, puis-je déterminer la direction avant l'arrêt du mouvement tactile?

Si je ne peux le faire qu'avec une bibliothèque externe, quelle est la meilleure?

merci.

27
madprops

J'ai eu quelques problèmes avec Ipad et je l'ai résolu avec deux événements

var ts;
$(document).bind('touchstart', function (e){
   ts = e.originalEvent.touches[0].clientY;
});

$(document).bind('touchend', function (e){
   var te = e.originalEvent.changedTouches[0].clientY;
   if(ts > te+5){
      slide_down();
   }else if(ts < te-5){
      slide_up();
   }
});
53

Vous devez enregistrer la dernière position de la touche, puis la comparer à la position actuelle.
Exemple approximatif:

var lastY;
$(document).bind('touchmove', function (e){
     var currentY = e.originalEvent.touches[0].clientY;
     if(currentY > lastY){
         // moved down
     }else if(currentY < lastY){
         // moved up
     }
     lastY = currentY;
});
37
Andy

La réponse d'Aureliano semble être vraiment exacte, mais d'une certaine manière, cela n'a pas fonctionné pour moi, donc en lui donnant les crédits, j'ai décidé d'améliorer sa réponse avec les éléments suivants:

var ts;
$(document).bind('touchstart', function(e) {
    ts = e.originalEvent.touches[0].clientY;
});

$(document).bind('touchmove', function(e) {
    var te = e.originalEvent.changedTouches[0].clientY;
    if (ts > te) {
        console.log('down');
    } else {
        console.log('up');
    }
});

J'ai simplement changé le 'touchend' événement pour 'touchmove'

14
Juan Herrera

J'ai créé un script qui garantira qu'un élément de votre document défilera sans faire défiler quoi que ce soit d'autre, y compris le corps. Cela fonctionne dans un navigateur ainsi que sur un appareil mobile/une tablette.

// desktop scroll
$( '.scrollable' ).bind( 'mousewheel DOMMouseScroll', function ( e ) {
    var e0 = e.originalEvent,
    delta = e0.wheelDelta || -e0.detail;

    this.scrollTop += delta * -1;
    e.preventDefault();
});

var lastY;
var currentY;

// reset touch position on touchstart
$('.scrollable').bind('touchstart', function (e){
    var currentY = e.originalEvent.touches[0].clientY;
    lastY = currentY;
    e.preventDefault();
});

// get movement and scroll the same way
$('.scrollable').bind('touchmove', function (e){
    var currentY = e.originalEvent.touches[0].clientY;
    delta = currentY - lastY;

    this.scrollTop += delta * -1;
    lastY = currentY;
    e.preventDefault();
});
3
Frank Snoek

Cette solution prend en compte les changements de direction que les réponses actuelles ne prennent pas. La solution ci-dessous prend également en charge la sensibilité au toucher; ceci lorsque l'utilisateur se déplace dans une direction mais au bout du doigt, les doigts de l'utilisateur poussent dans une direction différente, gâchant la direction réelle.

 var y = 0; //current y pos
 var sy = y; //previous y pos
 var error = 5; //touch sensitivity, I found between 4 and 7 to be good values. 

 function move(e) {
    //get current y pos
    y = e.pageY;

    //ingnore user jitter
    if (Math.abs(y - sy) > error) {
        //find direction of y
        if (y > sy) {
            //move down 
        } else {
            //move up
        }
        //store current y pos
        sy = y;
    }
}
2
manish