web-dev-qa-db-fra.com

vérifier si touchend vient après un glissement

J'ai du code qui change la classe d'une table. Sur un téléphone, parfois le tableau sera trop large pour l'écran et l'utilisateur fera glisser/défiler pour voir le contenu. Cependant, lorsqu'ils touchent et font glisser la table, cela déclenche le toucher à chaque glissement.

Comment tester pour voir si le touchend est le résultat d'un touch-drag? J'ai essayé de suivre le dragstart et le dragend, mais je ne pouvais pas faire fonctionner cela et cela semble une approche inélégante. Y a-t-il quelque chose que je pourrais ajouter ci-dessous qui déterminerait essentiellement: "Est-ce que ce contact est arrivé à la fin d'une traînée?"

$("#resultTable").on("touchend","#resultTable td",function(){ 
        $(this).toggleClass('stay');
});

Merci d'avance pour votre aide.

PS - en utilisant le dernier jquery, et bien qu'un clic normal fonctionne, il est très lent par rapport à touchend.

37
Konrad Lawson

Utilisez deux écouteurs:

Définissez d'abord une variable sur false:

var dragging = false;

Puis ontouchmove mis le glissement à vrai

$("body").on("touchmove", function(){
      dragging = true;
});

Ensuite, une fois le glissement terminé, vérifiez si le glissement est vrai, et si tel est le cas, comptez-le comme un toucher glissé:

$("body").on("touchend", function(){
      if (dragging)
          return;

      // wasn't a drag, just a tap
      // more code here
});

L'extrémité tactile se déclenchera toujours, mais se terminera d'elle-même avant l'exécution de votre script tap.

Pour vous assurer que la prochaine fois que vous touchez, il n'est pas déjà défini comme glissé, réinitialisez-le à faux au toucher.

$("body").on("touchstart", function(){
    dragging = false;
});
63
lededje

On dirait qu'une solution à mon problème se trouve ici:

http://alxgbsn.co.uk/2011/08/16/event-delegation-for-touch-events-in-javascript/

Ce bit de code détecte tout mouvement après le touchstart afin d'annuler le comportement de tap après tapend.

var tapArea, moved, startX, startY;

tapArea = document.querySelector('#list'); //element to delegate
moved = false; //flags if the finger has moved
startX = 0; //starting x coordinate
startY = 0; //starting y coordinate

//touchstart           
tapArea.ontouchstart = function(e) {

    moved = false;
    startX = e.touches[0].clientX;
    startY = e.touches[0].clientY;
};

//touchmove    
tapArea.ontouchmove = function(e) {

    //if finger moves more than 10px flag to cancel
    //code.google.com/mobile/articles/fast_buttons.html
    if (Math.abs(e.touches[0].clientX - startX) > 10 ||
        Math.abs(e.touches[0].clientY - startY) > 10) {
            moved = true;
    }
};

//touchend
tapArea.ontouchend = function(e) {

    e.preventDefault();

    //get element from touch point
    var element = e.changedTouches[0].target;

    //if the element is a text node, get its parent.
    if (element.nodeType === 3) { 
        element = element.parentNode;
    }

    if (!moved) {
        //check for the element type you want to capture
        if (element.tagName.toLowerCase() === 'label') {
            alert('tap');
        }
    }
};

//don't forget about touchcancel!
tapArea.ontouchcancel = function(e) {

    //reset variables
    moved = false;
    startX = 0;
    startY = 0;
};

Plus ici: https://developers.google.com/mobile/articles/fast_buttons

1
Konrad Lawson

Je dirais que vous ne pouvez pas faire la différence lorsque l'utilisateur fait glisser pour voir plus de contenu ou fait glisser l'élément autour. Je pense que vous devriez changer d’approche. Vous pouvez détecter s'il s'agit d'un appareil mobile, puis dessiner un interrupteur qui activera/désactivera le mouvement de l'élément.

0
KoU_warch

Pour raccourcir la solution de @lededge, cela peut aider.

$("body").on("touchmove", function(){
   dragging = true;
}).on("touchend", function(){
   if (dragging)
      return;
}).on("touchstart", function(){
   dragging = false;
});
0