jQuery (Balayer vs Touch) pageX et pageY reviennent 0

je joue avec les évènements touchstart et touchend sur mon iPhone. J'ai construit un exemple de page qui a div que si vous le touchez et faites défiler la page, il devrait retourner les coordonnées y des positions de début et de fin.

lien: http://jsbin.com/ibemom/2

le jQuery:

var touchStartPos;

$('.theDiv')
  .bind('touchstart', function(e){
    touchStartPos = e.pageY;
  })
  .bind('touchend', function(e){
    alert(touchStartPos + ' | ' + e.pageY)
  })   

quand je charge cette page sur mon iPhone, cependant, l'alerte continue de déclarer les deux valeurs comme zéro. Quelqu'un a vu le quelque chose ne va pas avec ce que j'ai?

mise à jour:

j'ai trébuché sur ce bout de code dans le projet jQuery Mobile: https://github.com/jquery/jquery-mobile/issues/734

Un commentaire de c'est resté:

 // (in iOS event.pageX and event.pageY are always 0 )

Il ne dit pas pourquoi c'est le cas, mais au moins j'ai trouvé quelqu'un d'autre qui voit la même chose. Creusera dans le code échantillon sur cette page pour voir si la solution est là.

UPDATE II:

bien, après avoir regardé le code échantillon dans le lien ci-dessus, il semble que cela retournera une valeur réelle:

e.originalEvent.touches[0].pageY

le piège est, je réalise maintenant que ce n'est pas tout à fait nécessaire. Il renvoie L'offset Y de la zone que j'ai touché dans l'objet auquel j'ai attaché l'événement en RELATION avec le document HTML...plutôt que de la fenêtre du navigateur.

mon but est de savoir où sur l'écran le toucher a commencé, et où il s'est terminé...et puis comparer les valeurs. S'ils sont un peu différents, alors nous supposons qu'un balayage a été effectué...plutôt que d'une touche.

UPDATE III:

je trouve aussi des références à ces exemples:

e.originalEvent.touches[0].pageX

event.targetTouches[0].pageY

même si je n'arrive pas à les faire marcher non plus. Les deux renvoient des erreurs non définies.

MISE À JOUR IV:

il semble qu'une solution soit de suivre offset() sur le document lui-même. Je peux appliquer un événement touchend au document, puis vérifier qu'il est en offset.

le problème avec ceci est que mon événement touchend se déclenchera d'abord sur l'élément sur ma page et ensuite il le lancera sur le document (bulles). Donc je ne peux pas vraiment déterminer si c'était une touche ou un balayage avant de devoir trouver quoi faire sur l'événement objects touchend.

Encore à méditer sur celui-ci...

17
demandé sur DA. 2011-08-18 02:09:25

4 réponses

Ok la réponse rapide est que vous ne pouvez pas détecter une touche lorsque le doigt sort de l'écran ( touchend ).

mon premier exemple prouve que: http://jsfiddle.net/Y4fHD/

maintenant à la solution. Ou appelez ça comme vous voulez. Peut-être qu'il est logique de ne pas détecter sur l'événement touchend parce que le toucher a terminé.

lient le manipulateur sur le touchmove événement: http://jsfiddle.net/Y4fHD/1/

var endCoords = {};
$(document.body).bind("touchmove", function(event) {
    endCoords = event.originalEvent.targetTouches[0];
});

Et ensuite utiliser la variable endCoords pour déterminer la dernière touche

$(document.body).bind("touchend", function(event) {
    $('p').text("Your end coords is: x: " + endCoords.pageX + ", y: " + endCoords.pageY);
});

OK essayez juste de taper sur votre appareil! Puis l'erreur est toujours ocure: Pourquoi? Parce que vous havn pas déplacé de votre toucher.

si nous sommes tous prêts dans le touchstart définit la variable endCoords nous sommes là: http://jsfiddle.net/Y4fHD/2/

var endCoords = {};
$(document.body).bind("touchstart touchmove", function(event) {
    endCoords = event.originalEvent.targetTouches[0];
});

Et ensuite utiliser la variable endCoords pour déterminer la dernière touche

$(document.body).bind("touchend", function(event) {
    $('p').text("Your end coords is: x: " + endCoords.pageX + ", y: " + endCoords.pageY);
});

Maintenant, essayez de toucher votre appareil!

quelques notes finales seront: faire aux variables: startCoords et endCoords puis les utiliser dans le touchend événement: http://jsfiddle.net/Y4fHD/3/

var startCoords = {}, endCoords = {};
$(document.body).bind("touchstart", function(event) {
    startCoords = endCoords = event.originalEvent.targetTouches[0];
});
$(document.body).bind("touchmove", function(event) {
    endCoords = event.originalEvent.targetTouches[0];
});
$(document.body).bind("touchend", function(event) {
    $('p').text("Your touch on the axis: " + Math.abs(startCoords.pageX-endCoords.pageX) + "x, " + Math.abs(startCoords.pageY-endCoords.pageY) + "y");
});

Note:

Aucun des les exemples ci-dessus sont testés, espère que cela fonctionne!

Math.abs me donne la valeur absolue d'un nombre eg: -5 devient 5

19
répondu andlrc 2013-09-15 18:26:12

il y a un morceau de code simplifié pour lequel je suis utilisé .myelement, dans l'original, il était curseur de la galerie

$(function() {
    var diff, tchs, del = 150,
    clk = function(el){
        if ( typeof(tchs) !== 'object' ) return; //we have nothing to do
        if ( (diff - tchs[tchs.length - 1].pageX) < 0 ) { //swipe right

        }
        else if ( (diff - tchs[tchs.length - 1].pageX) > 0 ) { //swipe left

        }
    };  
    $('.myelement').bind('touchstart touchmove', function(ev){
            var oev = ev.originalEvent, el = $(this);
            switch( ev.type.charAt(5) ){
                case 's': //touch start
                    diff = oev.pageX;
                    window.setTimeout(clk, del, el);
                break;
                case 'm': //touch move
                    tchs = oev.touches;
                break;
            }
    });
});

UPD: by the way, when I used MobiOne version 2.0.0m2 Testing Center logiciel il avait mis la valeur pageX touchend comme je m'y attendais, de sorte qu'il sonne mauvaise mise en œuvre qui peut facilement confondre si vous n'avez pas un accès rapide à l'appareil réel.

UPD2: ok, inspiré par la rétroaction positive :) réalisé version un peu compliquée, qui permet de détecter droite, gauche, haut et en bas swipes, il a encore besoin d'être nettoyé, mais vous avez l'idée.

$(function () {
    var ftch, // first touch cache
    lck = Math.sin(Math.PI / 4); //lock value, sine of 45 deg configurable

    var defSwipeDir = function (el, tchs) { // need define swaping direction, for better UX
        if (typeof (tchs) !== 'object') return 0; // check if there was any movements since   first touch, if no return 0
        var ltch = tchs[tchs.length - 1], // last touch object
            dx = ltch.pageX - ftch.pageX,
            dy = ltch.pageY - ftch.pageY,
            hyp = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)),
            sin = dy / hyp,
            cos = dx / hyp,
            dir;

        if (Math.abs(cos) >= lck) { // left or right swape
            dir = cos > 0 ? 'r' : 'l';
        } else { // up or down
            dir = sin < 0 ? 'u' : 'd';
        }
        el.trigger('swipe', dir); // trigger custom swipe event
        return dir; // and return direction too
    }

    $('.myelementTouchDetection').on('touchstart touchmove swipe', function (ev, d) {
        var oev = ev.originalEvent,
            myelementTouchDetection = $(this),
            dir; // you may know swipes on move event too

        switch (ev.type) {
            case 'touchstart':
                ftch = oev;
                break;
            case 'touchmove':
                dir = defSwipeDir(myelementTouchDetection, oev.touches);
                return false // cancel default behaiviour
                break;
            case 'swipe':
                switch (d) {
                    case 'r': // swipe right
                        console.log('swipe right');
                        break;
                    case 'l': // swipe left
                        console.log('swipe left');
                        break;
                    case 'u': // swipe up
                        console.log('swipe up');
                        break;
                    case 'd': // swipe down
                        console.log('swipe down');
                        break;
                }
                break;
        }
    })
});
2
répondu dmi3y 2012-11-07 15:34:22

la réponse de NULL, ci-dessus, a bien fonctionné pour moi, sauf que vous ne pouvez pas affecter startCoords à endCoords dans la fonction liée à touchstart. Ils pointent alors vers le même objet de sorte que lorsque endCoords est mis à jour, startCoords le fait aussi. Lorsque l'événement touchend se déclenche, startCoords sera toujours égal à endCoords.

code mis à jour ci-dessous. Cela a fonctionné pour moi sur un iPad 3 en utilisant Safari sur iOS 6.0. Modifié aussi pour corriger une erreur de maths et d'affichage et supprimer Maths.abs() à l'intérieur du touchend lié à la fonction. Également ajouté un événement.preventDefault () appelle à l'intérieur de la fonction liée à touchmove, pour que cela fonctionne sur Google Chrome sur iOS aussi.

var startCoords = {}, endCoords = {};

$(document.body).bind("touchstart", function(event) {
    endCoords = event.originalEvent.targetTouches[0];
    startCoords.pageX = event.originalEvent.targetTouches[0].pageX;
    startCoords.pageY = event.originalEvent.targetTouches[0].pageY;
});

$(document.body).bind("touchmove", function(event) {
    event.preventDefault();
    endCoords = event.originalEvent.targetTouches[0];
});

$(document.body).bind("touchend", function(event) {
    $('p').text("Your touch on the axis: " + (endCoords.pageX-startCoords.pageX) + "x, " + (endCoords.pageY-startCoords.pageY) + "y");
});
2
répondu Joseph Cheek 2013-01-25 05:03:38

voici ce qui marche pour moi....

$('.someClass').bind('touchmove',function(e){
  e.preventDefault();
  var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];
  var elm = $(this).offset();
  var x = touch.pageX - elm.left;
  var y = touch.pageY - elm.top;
  if(x < $(this).width() && x > 0){
      if(y < $(this).height() && y > 0){
              //your code here
      }
     }
});
1
répondu TJS101 2012-03-10 14:47:32