132 votes

problème de vol stationnaire iPad/iPhone provoque l’utilisateur de double cliquer sur un lien

J’ai quelques sites que j’ai construit des fois il y a, qui utilisent des événements de souris de jquery... Je viens de recevoir un ipad et j’ai remarqué que toutes la souris sur événements sont traduits en clics... Si par exemple je dois faire deux clics au lieu d’un... (le premier vol plané, que le clic réel)

existe-t-il une solution de contournement prête à résoudre ce problème ? peut-être une commande jquery que je devrais avoir utilisé au lieu de mouseover/out etc... Merci !

207voto

cduruk Points 1130

N’avez pas testé cette entièrement mais depuis iOS touch déclenche les événements, cela pourrait fonctionner, en supposant que vous êtes dans un cadre de jQuery.

L’idée est que WebKit Mobile se déclenche une événement à la fin d’un robinet pour nous écouter pour cela et ensuite rediriger le navigateur dès qu’un événement a été déclenché sur un lien.

39voto

MacFreek Points 391

Il n'est pas entièrement claire de ce que votre question est de savoir, mais si vous voulez juste pour éliminer le double-clic, tout en conservant l'effet hover pour la souris, mon conseil est de:

  • Ajouter des effets de survol sur touchstart et mouseenter.
  • Supprimer les effets de survol sur mouseleave, touchmove et click.

Arrière-plan

Afin de simuler une souris, les navigateurs tels que Webkit mobile incendie, les événements suivants si un utilisateur touche et libère un doigt sur l'écran tactile (comme l'iPad) (source: Toucher Et de la Souris sur html5rocks.com):

  1. touchstart
  2. touchmove
  3. touchend
  4. 300ms retard, d'où le navigateur assure que c'est un simple toucher, pas un double tap
  5. mouseover
  6. mouseenter
    • Remarque: Si un mouseover, mouseenter ou mousemove événement change le contenu de la page, les événements suivants sont jamais tiré.
  7. mousemove
  8. mousedown
  9. mouseup
  10. click

Il ne semble pas possible tout simplement de dire la webbrowser à ignorer les événements de souris.

Ce qui est pire, si un événement mouseover modifie le contenu de la page, cliquez sur l'événement n'est jamais tiré, comme expliqué sur le Web Safari Contenu du Guide de gestion des Événements, en particulier la figure 6.4 dans Un Doigt Événements. Ce qu'est exactement une "modifier le contenu" est, dépendra de navigateur et sa version. J'ai trouvé que pour iOS 7.0, un changement de couleur de fond n'est pas (ou plus?) une modification du contenu.

Solution Expliqué

Pour récapituler:

  • Ajouter des effets de survol sur touchstart et mouseenter.
  • Supprimer les effets de survol sur mouseleave, touchmove et click.

Notez qu'il n'y a pas d'action sur touchend!

Cela fonctionne bien pour les événements de la souris: mouseenter et mouseleave (légèrement versions améliorées de mouseover et mouseout) sont licenciés, et d'ajouter et de supprimer le hover.

Si l'utilisateur en fait clicks un lien, le hover effet est également supprimé. Ceci s'assurer qu'elle est supprimée si l'utilisateur appuie sur le bouton retour dans le navigateur web.

Cela fonctionne aussi pour les événements tactiles: sur touchstart vol stationnaire effet est ajouté. Il est ""pas" " enlevé sur touchend. Il est ajouté à nouveau sur mouseenter, et puisque cela ne cause pas de changements de contenu (il a déjà été ajouté), l' click événement est également déclenché, et le lien est suivi sans la nécessité pour l'utilisateur de cliquer à nouveau!

Les 300 ms délai d'un navigateur a entre un touchstart événement et click est effectivement mis en bon usage car le hover effet sera montré durant ce laps de temps.

Si l'utilisateur décide d'annuler le clic, déplacez le doigt ne suffit donc comme d'habitude. Normalement, c'est un problème car aucune mouseleave événement est déclenché, et le hover effet reste en place. Heureusement, cela peut être facilement corrigé en supprimant l'effet hover sur touchmove.

Ça y est!

Notez qu'il est possible de supprimer toutes les 300 ms délai, par exemple à l'aide de la FastClick de la bibliothèque, mais c'est hors de portée pour cette question.

Des Solutions Alternatives

J'ai constaté les problèmes suivants avec les options suivantes:

  • la détection du navigateur: Extrêmement sujettes à des erreurs. Suppose qu'un périphérique a la souris ou tactile, tandis qu'une combinaison des deux va devenir de plus en plus fréquente lorsque les écrans tactiles prolifirate.
  • CSS détection de médias: La seule CSS seule solution, je suis au courant. Encore sujette à des erreurs, et suppose encore que c'est un appareil tactile ou de souris, alors que les deux sont possibles.
  • Émuler l'événement click en touchend: Ce, à tort, suivez le lien, même si l'utilisateur ne voulait défiler ou de zoom, sans l'intention de les en cliquant sur le lien.
  • Utiliser une variable pour supprimer les événements de la souris: Ce set une variable en touchend qui est utilisé comme un si-condition dans la suite des événements de souris empêche les modifications de l'état à ce point dans le temps. La variable est réinitialisée dans l'événement click. C'est une solution décente si vous ne voulez vraiment pas un effet hover sur les interfaces tactiles. Malheureusement, cela ne fonctionne pas si un touchend est déclenché pour une autre raison et non sur l'événement est déclenché (par exemple, l'utilisateur défilement ou zoom), et est par la suite essayer de suite le lien avec une souris (j'.e sur un appareil à la fois la souris et une interface tactile).

Lectures Complémentaires

Voir aussi iPad/iPhone double-cliquez problème et Désactiver les effets de survol sur les navigateurs mobiles.

20voto

Pavel Bogatinov Points 111

Semble y avoir un CSS solution, après tout. Le motif Safari attend un deuxième contact est à cause de l'image d'arrière-plan (ou les éléments) vous affectent généralement sur le :hover événement. Si il n'y a pas d'être montré - vous n'aurez pas de problèmes. La solution est de cibler plate-forme iOS secondaire fichier CSS (ou le style dans le cas d'un JS approche) qui remplace les :hover fond d'hériter par exemple et de le garder caché les éléments que vous allez afficher au survol de la souris:

Voici un exemple de CSS et de HTML - un produit bloc avec un étoilé de l'étiquette sur le dessus de la souris:

HTML:

<a href="#" class="s"><span class="s-star"></span>Some text here</a>

CSS:

.s {
   background: url(some-image.png) no-repeat 0 0;

}
.s:hover {
   background: url(some-image-r.png) no-repeat 0 0;
}

.s-star {
   background: url(star.png) no-repeat 0 0;
   height: 56px;
   position: absolute;
   width: 72px;
   display:none;
}

.s:hover .s-star {
   display:block;
}

Solution (secondaire CSS):

/* CSS */
/* Keep hovers the same or hidden */
.s:hover {
   background:inherit;
}
.s:hover .s-star {
   display:none;
}

5voto

Adauto Points 326

Ce qui a fonctionné pour moi est ce que d'autres ici ont déjà dit:

Ne pas afficher/masquer les éléments sur le vol stationnaire ou mousemove (ce qui est le cas dans mon cas).

Voici ce que Apple dit (https://developer.apple.com/library/iOS/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html):

Un élément est cliquable d'un lien, d'élément de formulaire, à l'image de la carte de la zone, ou de tout autre élément avec mousemove, mousedown, mouseup, ou onclick gestionnaires

Si l'utilisateur appuie sur un bouton de l'élément, événements arrivent dans cet ordre: passage de la souris, mousemove, mousedown, mouseup, et cliquez sur. Aussi, si le contenu de la page change sur l'événement mousemove, pas d'événements subséquents dans la séquence sont envoyés. Ce comportement permet à l'utilisateur de taper dans le nouveau contenu.

Donc, vous pouvez utiliser @woop solution: détecter le userAgent, vérifier si c'est l'appareil iOS et puis de lier l'événement. J'ai fini à l'aide de cette technique, car elle convient à mes besoins et il est plus logique de ne pas lier passez événements lorsque vous ne souhaitez pas.

Mais... si vous ne voulez pas salir avec userAgents et encore masquer/afficher des éléments sur le vol stationnaire/mousemove, j'ai trouvé, vous pouvez le faire en utilisant javascript natif, comme ceci:

$("body").on("mouseover", function() {
       document.getElementsByTagName("my-class")[0].style.display = 'block'; //show element
       document.querySelector(".my-selector div").style.display = 'none'; // hide element
});

Cela fonctionne sur la version de Bureau et rien ne sera fait sur la version mobile.

Et pour un peu plus de compatibilité...

$("body").on("mouseover", function() {
   if (document.getElementsByTagName && document.querySelector) { // check compatibility
       document.getElementsByTagName("my-class")[0].style.display = 'block'; //show element
       document.querySelector(".my-selector div").style.display = 'none'; // hide element
    } else {
        $(".my-class").show();
        $(".my-selector div").hide();
    }
});

3voto

woop Points 21

solution de cduruk a été très efficace, mais a causé des problèmes sur quelques parties de mon site. Parce que j’utilisais déjà jQuery pour ajouter la classe hover CSS, la solution la plus simple était d’il suffit pas d’ajouter la classe hover CSS sur des appareils mobiles (ou plus précisément, à seulement ajouter quand pas sur un appareil mobile).

Voilà l’idée générale :

  • code réduit à titre illustratif

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