46 votes

Empêcher les événements d'émulation de souris (c'est-à-dire les clics) des événements tactiles dans Mobile Safari / iPhone à l'aide de Javascript

En faisant une seule page Javascript application interactive des éléments du DOM, j'ai trouvé que le "mouseover-mousemove-mousedown-mouseup-click" séquence arrive tout un tas après le "touchstart-touchmove-touchend" la séquence des événements.

J'ai aussi trouvé qu'il est possible d'éviter le "mouse*-click" événements de se produire, par un "event.preventDefault()" au cours de l' touchstart événement, mais seulement alors, et non pas lors de l' touchmove et touchend. C'est une étrange conception de, parce que parce que il n'est pas possible de connaître lors de la touchstart encore si l'utilisateur tente de glisser ou faire glisser ou appuyez/cliquez sur l'élément.

J'ai fini par mettre en place un "ignore_next_click" drapeau quelque part lié à un timestamp, mais ce n'est évidemment pas très propre.

Quelqu'un sait d'une meilleure façon de faire cela, ou sommes-nous raté quelque chose?

Notez que tandis qu'un "clic" peut être reconnu comme un "touchstart-touchend" de la séquence (c'est à dire pas "touchmove"), il y a certaines choses, comme les touches de focus d'entrée, qui ne peut se faire que pendant un bon click événement.

5voto

Colin Godsey Points 728

J'ai couru dans les mêmes problèmes de la croix-plate-forme HTML5/JS apps. La seule vraie réponse pour moi était de preventDefault sur les événements tactiles, et en fait de gérer au toucher unis et le feu sur, traîne, etc. les évènements sur mon propre selon ma logique. Cela sonne beaucoup plus ardue qu'elle ne l'est vraiment, mais le imité de la souris/les événements de la souris fonctionne parfaitement sur la plupart des navigateurs mobiles.

Cliquez sur et la souris séquence sont là pour votre confort (et la compatibilité). Ma règle d'or - si c'est pour votre commodité, mais c'est gênant, le meilleur de la tuer.

Aussi loin que l'entrée des boîtes, ils ont seulement besoin de la touchend événements. J'ai tué la souris/les événements de la souris et était encore en mesure de laisser les navigateurs mobiles répondre correctement aux touches sur les intrants. Si elle est en vous donnant toujours des problèmes, vous pouvez modifier le gestionnaire d'événement à seulement supprimer les événements sur la non-entrées:

function touchHandler(event) {
    var shouldIgnore = event.target != null 
          && ( event.target.tagName.toLowerCase() == "input" || event.target.tagName.toLowerCase() == "textarea" );

    if(!shouldIgnore) e.preventDefault();
}

4voto

maxkfranz Points 1398

J'ai fait une solution moi-même, puisque je n'ai pas trouvé une solution suffisante ailleurs:

   var isTouch = ('ontouchstart' in window);

   function kill(type){
     window.document.body.addEventListener(type, function(e){
       e.preventDefault();
       e.stopPropagation();
       return false;
     }, true);
   }

   if( isTouch ){
     kill('mousedown');
     kill('mouseup');
     kill('click');
     kill('mousemove');
   }

La vérification de l' isTouch laisse les choses fonctionnent normalement sur la souris-périphériques d'entrée, mais tue l'émulé événements sur Safari/iOS. L'astuce est d'utiliser useCapture = true dans l'appel d' addEventListener nous avons donc ramasser tous les événements de la souris dans la page sans avoir à bidouiller le code sur le web application. Voir la doc de la fonction ici: https://developer.mozilla.org/en-US/docs/DOM/EventTarget.addEventListener?redirectlocale=en-US&redirectslug=DOM%2Felement.addEventListener

Edit:

Maintenant que les bibliothèques pour traiter de cette question sont mieux, vous pouvez utiliser quelque chose comme Fastclick comme une alternative (https://github.com/ftlabs/fastclick).

0voto

robocat Points 1567

La création de boutons rapides pour les applications Web mobiles a leur solution au problème.

Sachez également que lorsque vous utilisez IE10 preventDefault () n'arrête pas les événements de souris fantômes / synthétiques / émulés après un événement MSPointerDown, donc une véritable solution multi-navigateur est plus difficile.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X