Touches multiples: événement de touché déclenché uniquement lorsqu'un mouvement de toucher survient

J'aimerais ajouter des fonctionnalités multitouch à mon application javascript lorsqu'elle est accessible depuis un périphérique ios (et peut-être Android plus tard).

Je souhaite fournir une fonctionnalité de type changement de clé : l'utilisateur peut contenir un bouton sur l'écran avec un seul doigt, et pendant que vous appuyez sur ce bouton, le comportement d'une action de prise de touche sur le reste de l'écran est légèrement différent de la touche classique.

Le problème auquel je suis confronté est que je ne reçois aucun événement de touche pour le doigt de taraudage, à moins qu'un tic tac tactile ne soit tiré pour le premier doigt qui maintient le bouton de la touche Maj .

Parce que l'écran est très sensible, les événements tactiles sont facilement déclenchés et, dans la plupart des cas, tout fonctionne bien.

Mais lorsque le doigt de l'utilisateur est un peu trop silencieux, le taraudage n'est pas détecté jusqu'à ce que l'utilisateur déplace son doigt un peu. Cela induit un «retard» variable entre le taraudage et l'action qui se produit sur l'écran (le délai peut varier et durer quelques secondes si l'utilisateur est très calme). Ma supposition est que ce délai amènera l'utilisateur à frapper de nouveau et donc à déclencher l'action une seconde fois, ce que je ne veux pas !

Vous pouvez le tester ici avec votre ipad / iphone: http://jsfiddle.net/jdeXH/8/

Essayez de faire en sorte que le corps reste vert pendant quelques secondes en tenant votre doigt très immobile sur le div cyan tout en tapotant sur le div rouge.

Ce comportement est-il attendu? Existe-t-il une solution connue pour le problème? Je m'attendais à ce que l'événement touchend soit déclenché tout de suite lorsque le doigt est retiré de l'écran.

J'ai testé ceci avec iOS 5.1.1 (ipad1 et iphone4s)

Edit : trouvé une question similaire Multitouch touchEvents ne sont pas déclenchés comme ils le devraient sur Safari Mobile

Eh bien, il semble que le bug a dérangé certaines personnes plus que moi , ils ont déposé un bug directement à Apple, et après quelques années, il est maintenant corrigé dans iOS6 🙂

D'accord, c'est un mal de tête. Oui, il y a deux problèmes connus. Tout d'abord, Safari ne dérange pas le fait de déclencher l'événement touchEnd, à moins qu'il n'y ait un contactMove quelque part, même si le touchMove ne fait pas vraiment beaucoup.

Deuxièmement, Chrome Mobile est aussi une belle expérience, comme sur de nombreux appareils Android, l'événement TouchEnd ne déclenche pas du tout, peu importe ce que vous faites. Donc, de mon expérience:

  • Mettre en œuvre un événement touchStart qui enregistre la coordonnée de départ, etc.
  • Implégettez un événement touchMove qui fait exactement la même chose que TouchEnd, mais assurez-vous que le rappel ne déclenche pas plus d'une fois. Utilisez un drapeau booléen défini dans une portée supérieure ou quelque chose comme ça.
  • Importez l'événement touchEnd normal qui ne doit déclencher que si touchMove n'a pas déjà déclenché le rappel, en utilisant le même indicateur booléen défini dans une portée supérieure.

Ok, j'ai mis en œuvre cette solution et ça semble fonctionner.

//Initialize the tap touch function ManageTapTouch() { this.__enabled__ = false; } ManageTapTouch.prototype.init = function(){ $("#hold").bind('touchstart', $.proxy(this.__enable__, this)); $('#hold').bind('touchend', $.proxy(this.__disable__, this)); $('#tap').bind('touchstart', $.proxy(this.__changeColorOnHold__, this)); $('#tap').bind('touchend', $.proxy(this.__changeColorOnOut__, this)); }; ManageTapTouch.prototype.__enable__ = function(event) { this.__enabled__ = true; }; ManageTapTouch.prototype.__disable__ = function(event) { this.__enabled__ = false; $('body').css('background-color', 'blue'); }; ManageTapTouch.prototype.__changeColorOnHold__ = function(event) { if (this.__enabled__){ $('body').css('background-color', 'black'); } }; ManageTapTouch.prototype.__changeColorOnOut__ = function(event) { $('body').css('background-color', 'blue'); }; new ManageTapTouch().init(); 

Vous pouvez le voir en cours d'exécution ici: http://jsfiddle.net/Tb6t6/15/

Aussi, vous pouvez essayer une autre façon sur l'iPhone en utilisant multitouch avec: event.originalEvent.touches[0].pageX et event.originalEvent.touches[0].pageY où l'index est le doigt sur l'écran et l'événement est l'événement déclenché sur TouchStart . Avec ces sujets, vous pouvez implémenter votre propre version de cette action ou utiliser celle que je propose ici.

Donc, il semble que vous ayez atteint l'un de ces scénarios qui ne peuvent pas être évités et que vous n'aurez que des pirates de buggy. Vous créez une fonctionnalité d'interface utilisateur qui n'est pas tout à fait la «norme», mais semble avoir une certaine promesse (j'aime … j'aime). La question à poser à ce stade de la technologie est « comment puis-je forcer l'utilisateur à glisser son doigt pour tenir le changement ».

Avec l'aide d'un bon designer, je pense que vous pourriez créer un bouton de basculement à glissière similaire à un commutateur à bascule … où un utilisateur doit être maintenu enfoncé pour allumer l'interrupteur. À la sortie, le commutateur retournerait à la position "off". Je mentionne un designer parce que le bouton doit ressembler à ce qu'il se comporte. Peut-être que certains des commentaires peuvent être créatifs.