2013-03-06 88 views
8

發生touchend事件時,是否可以知道觸摸開始的位置(touchstart座標)?乍一看,這看起來像touchstart中保存座標一樣簡單,但假設事件被附加到具有特定類的所有DOM元素(即.special)。現在考慮我用.special類碰觸兩個物體,然後從我的手指上取下手指。我不能只看最後保存的價值,因爲它可能是我舉起的第一根手指。在touchend事件中檢索touchstart座標

如何在這些情況下檢索touchstart座標?

+0

爲什麼不存儲觸摸開始時的x,y,然後在釋放後再檢查這個... – 2013-03-08 12:31:24

+0

我已經更新了我的答案,希望這是您正在尋找的內容。 – strah 2013-03-09 21:41:10

回答

10

touchstart您可以存儲您可能需要的所有值(如x,y,target,等等)。在touchend上,您可以檢索所有存儲的值,這要歸功於Touch.identifier值,每個觸摸都應該是唯一的值。

我創建了一個概念證明這裏: http://jsbin.com/adifit/3/

下面的代碼只跟蹤的xy位置,但如果需要,你可以跟蹤任何屬性。

代碼背後的想法是:

  1. touchstart創建一個對象和所有陣列
  2. 在內部的數據(包括觸摸ID)
  3. 存儲該對象存儲在touchend檢查如果找到,則嘗試在數組中找到相應的對象。
  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是不用於其他任何東西。

+1

@ alex23感謝您的編輯。我恢復它,雖然它刪除了相當重要的一些功能(和代碼會拋出錯誤)。 – strah 2013-03-16 05:36:07

+0

你太棒了! – MastAvalons 2013-11-06 20:45:42

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。但它表現出類似的概念。