2011-05-04 2 views
10

J'essaie d'obtenir des coordonnées tactiles par rapport à la viewport du navigateur des événements tactiles (tels que touchstart). J'ai essayé de les obtenir à partir des propriétés clientX/Y, mais les deux retournent des valeurs incluant le défilement. Ceci est contraire à la spécification, car le client X/Y doit retourner les coordonnées sans défilement.Inclut Touch Events clientX/Y défilant ou non?

  • J'ai essayé d'ajouter/supprimer la balise meta viewport - sans succès.
  • Je l'ai testé dans iOS 4.3 sur iPhone et Fennec tous les soirs - les deux retournent les valeurs avec le défilement.

Qu'est-ce que je fais mal?

Merci

Répondre

7

Essayez cette

event.touches[0].pageX 

Notez qu'il est toujours event.touches même si vous définissez votre événement comme celui-ci (en utilisant jquery ici)

$("body").bind('touchmove', function(e){ 
//stops normal scrolling with touch 
e.preventDefault(); 

console.log(event.touches[0].pageX) 

}) 

;

Le Safari guide donne plus de détails

+0

Oui, je le récupère par event.touches [0] .clientX ... mais je ne sais toujours pas pourquoi (iOS au moins) rapporte pageX et clientX comme étant identiques (en fait, ils devraient différer selon le décalage de la fenêtre) – kuvik

+1

Vous avez raison, semble être un bug. Vous pouvez le contourner en décalant le défilement de la page '(event.targetTouches [0] .screenY - $ (window) .scrollTop())' –

+0

e.originalEvent.touches [0] .clientY travaille pour moi –

14

Tu ne fais rien de mal. C'est un bug dans les anciennes versions de webkit qui se produisent lorsque la page est défilée. J'ai vu ce bug dans iOS4 et un bug différent dans Android 4.0.

J'ai trouvé un moyen de détecter les bogues et de calculer les valeurs correctes. Espérons que cela peut être utile pour d'autres:

function fixTouch (touch) { 
    var winPageX = window.pageXOffset, 
     winPageY = window.pageYOffset, 
     x = touch.clientX, 
     y = touch.clientY; 

    if (touch.pageY === 0 && Math.floor(y) > Math.floor(touch.pageY) || 
     touch.pageX === 0 && Math.floor(x) > Math.floor(touch.pageX)) { 
     // iOS4 clientX/clientY have the value that should have been 
     // in pageX/pageY. While pageX/page/ have the value 0 
     x = x - winPageX; 
     y = y - winPageY; 
    } else if (y < (touch.pageY - winPageY) || x < (touch.pageX - winPageX)) { 
     // Some Android browsers have totally bogus values for clientX/Y 
     // when scrolling/zooming a page. Detectable since clientX/clientY 
     // should never be smaller than pageX/pageY minus page scroll 
     x = touch.pageX - winPageX; 
     y = touch.pageY - winPageY; 
    } 

    return { 
     clientX: x, 
     clientY: y 
    }; 
} 

Cette fonction doit être appelée pour chaque touche dans le tableau event.touches.