在touchend事件中获取touchstart坐标

9
当触发touchend事件时,是否有可能知道触摸开始的位置(touchstart坐标)?乍一看,这似乎很容易,只需在touchstart期间保存坐标即可。但是考虑到该事件已附加到所有具有特定类(即.special)的DOM元素上。现在假设我用.special类触碰了两个对象,然后放开了一个手指。我不能仅查看最后保存的值,因为它可能是我抬起的第一个手指。
在这种情况下,如何检索touchstart坐标?

为什么不在触摸开始时存储 x 和 y,并在释放时检索它? - Sudip Pal
我已经更新了我的答案,希望这就是你所寻找的。 - strah
2个回答

10

touchstart 事件中,您可以存储所有可能需要的值(例如 x、y、目标等)。在 touchend 事件中,您可以通过 Touch.identifier 值检索所有已存储的值,该值应对于每个触摸操作是唯一的。

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

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

代码的基本思路如下:

  1. touchstart 事件中创建一个对象并将所有数据存储在其中(包括触摸 ID)
  2. 将此对象存储在数组中
  3. touchend 事件中,检查触摸操作的 ID,并尝试在数组中找到相应的对象
  4. 如果找到,则完成。

代码如下:

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未用于其他任何事情。

上面的代码使用了jQuery,但仅用于方便在屏幕上显示结果,未用于其他任何用途。


1
@alex23 感谢您的编辑。不过我还原了它,因为它删除了相当重要的功能(而且代码会抛出错误)。 - strah

4

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

W3C规范关于touchmove事件

当此触摸点放置在表面上时,此事件的目标必须是与接收到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有一个很好的解决方案,我的方法简化了一些,只检查事件目标,而不是触摸ID。但它演示了类似的概念。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接