在touchend事件中检索touchstart坐标

时间:2013-03-06 06:58:49

标签: javascript touch

当触摸事件发生时,是否可以知道触摸的开始位置(触摸开始坐标)?乍一看,这看起来像在touchstart期间保存坐标一样简单,但假设事件附加到具有特定类的所有DOM元素(即.special)。现在考虑我用.special类触摸两个对象然后将手指从一个上抬起。我不能只看最后保存的值,因为它可能是我举起的第一根手指。

如何在这些情况下检索touchstart坐标?

2 个答案:

答案 0 :(得分:10)

touchstart上,您可以存储您可能需要的所有值(例如x,y,target等)。在touchend上,您可以检索所有存储的值,这要归功于Touch.identifier值,每次触摸都应该是唯一的。

我在这里创建了一个概念验证: http://jsbin.com/adifit/3/

以下代码仅跟踪xy位置,但您可以根据需要跟踪任何属性。

代码背后的想法是:

  1. on touchstart创建一个对象并存储所有数据(包括触摸ID)
  2. 将此对象存储在数组
  3. on touchend检查触摸的ID并尝试在数组中找到相应的对象
  4. 如果发现,我们已经完成了。
  5. 代码:

    var touches = [];
    var cons;
    
    $(init);
    
    function init()
    {
      cons = $("#console");
      document.getElementById("area").addEventListener("touchstart", onTouchStart);
      document.addEventListener("touchend", onTouchEnd);
      document.addEventListener("touchcancel", onTouchEnd);
    }
    
    function onTouchStart(e)
    {
      e.preventDefault();
      var touchList = e.changedTouches;
      var touch;
      for(var i = 0; i < touchList.length; i++)
      {
        cons.html(cons.html() + "startX: " + touchList[i].screenX + ", id: " + touchList[i].identifier + "<br/>");
        touch = {x: touchList[i].screenX, y: touchList[i].screenY, id: touchList[i].identifier};
        touches.push(touch);
      }
    }
    
    function onTouchEnd(e)
    {
      cons.html(cons.html() + "<strong>TouchEnd:</strong><br/>");
      var touchList = e.changedTouches;
      var touch;
      for(var i = 0; i < touchList.length; i++)
      {
        touch = {x: touchList[i].screenX, y: touchList[i].screenY, id: touchList[i].identifier};
        for (var j = touches.length - 1; j >= 0 ; j--)
        {
          if (touches[j].id == touch.id)
          {
            cons.html(cons.html() + "<strong>startX: "+ touches[j].x+ ", id: " + touchList[i].identifier + "</strong><br/>");
            touches.splice(j, 1);
          }
        }
      }
    }
    

    上面的代码使用jQuery,但它仅用于方便在屏幕上显示结果,jQuery不用于其他任何内容。

答案 1 :(得分:4)

可以通过touch连接不同的event.target个事件。

W3C specs on touchmove event

  

当此触摸点放置在曲面上时,此事件的目标必须与接收touchstart事件的元素相同,即使触摸点已移出目标元素的交互区域之外。

因此,您要跟踪event.target

document.addEventListener("touchstart", onTouchStart);
document.addEventListener("touchend", onTouchEnd);
document.addEventListener("touchcancel", onTouchCancel);

var targets = []; // create array with all touch targets 
                  // still needs some sort of garbage collection though

function onTouchStart(event){
   targets.push(event.target); // add target to array
}

function onTouchEnd(event){
    // loop through array to find your target
    for (var i = 0; i < targets.length; i++) {
        if (targets[i] == event.target) { //test target
            // this is your match! Do something with this element
            targets[i].splice(i,1); // remove entry after event ends;
        }
    }
}

function onTouchCancel(event){
    // loop through array to find your target
    for (var i = 0; i < targets.length; i++) { 
        if (targets[i] == event.target) { //test target
            // Just delete this event
            targets[i].splice(i,1); // remove entry after event ends;
        }
    }
}  

注意:未经过测试。我看到@Strah有一个很好的解决方案,我的有点简化,只检查event.target,而不是touch-id。但它展示了类似的概念。