checking if touchend comes after a drag

风流意气都作罢 提交于 2019-12-03 04:44:26

问题


I have some code which changes the class of a table. On a phone, sometimes the table will be too wide for the screen and the user will drag/scroll about to see the contents. However, when they touch and drag the table around, it triggers touchend on every drag.

How do I test to see whether the touchend came as a result of a touch-drag? I tried tracking dragstart and dragend but I couldn't get that to work and it seems an inelegant approach. Is there something I could add to below which would essentially determine, "Did this touchend come at the end of a drag?"

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

My thanks in advance for your help.

PS - using latest jquery, and while a regular click works, it is very slow in comparison to touchend.


回答1:


Use two listeners:

First set a variable to false:

var dragging = false;

Then ontouchmove set dragging to true

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

Then on drag complete, check to see if dragging is true, and if so count it as a dragged touch:

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

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

The touch end will still fire, but will terminate itself before your tap script is run.

To ensure the next time you touch it isn't already set as dragged, reset it back to false on touch down.

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



回答2:


Looks like one solution to my problem is found here:

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

This bit of code detects any move after touchstart in order to abort tap behavior after 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;
};

More here: https://developers.google.com/mobile/articles/fast_buttons




回答3:


I would say you can't tell the difference when the user drags to see more content or drag the element arround. I think you should change the approach. You could detect if it's a mobile device and then draw a switch that will enable/disable the movement of the element.




回答4:


To shorten the solution of @lededge, this might help.

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


来源:https://stackoverflow.com/questions/12690620/checking-if-touchend-comes-after-a-drag

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!