J'ai des menus css sur mon site qui se développent avec :hover
(sans js)
Cela fonctionne de manière semi-interrompue sur les iDevices, par exemple, un robinet activera la :hover
règle et développera le menu, mais en tapant ailleurs ne supprimera pas le :hover
. De plus, s'il y a un lien à l'intérieur de l'élément qui est :hover
'ed, vous devez appuyer deux fois pour activer le lien (premier déclencheur tap :hover
, deuxième lien déclencheur tap).
J'ai pu faire fonctionner les choses bien sur iPhone en liant l' touchstart
événement.
Le problème est que parfois le safari mobile choisit toujours de déclencher la :hover
règle depuis le css au lieu de mes touchstart
événements!
Je sais que c'est le problème car lorsque je désactive tous les :hover
manuellement règles dans le css, le safari mobile fonctionne très bien (mais les navigateurs classiques ne le font évidemment plus).
Existe-t-il un moyen «d'annuler» dynamiquement les :hover
règles pour certains éléments lorsque l'utilisateur est en safari mobile?
Voir et comparer le comportement iOS ici: http://jsfiddle.net/74s35/3/ Remarque: que seules certaines propriétés css déclenchent le comportement en deux clics, par exemple display: none; mais pas de fond: rouge; ou texte-décoration: souligné;
la source
Réponses:
J'ai trouvé que ": hover" est imprévisible dans Safari iPhone / iPad. Parfois, appuyez sur l'élément pour faire de cet élément ": hover", alors que parfois il dérive vers d'autres éléments.
Pour le moment, j'ai juste un cours «sans contact» au corps.
Et ayez toutes les règles CSS avec ": hover" ci-dessous ".no-touch":
Quelque part dans la page, j'ai javascript pour supprimer la classe sans contact du corps.
Cela n'a pas l'air parfait, mais cela fonctionne quand même.
la source
:hover
n'est pas le problème ici. Safari pour iOS suit une règle très étrange. Il tiremouseover
et d'mousemove
abord; si quelque chose est changé pendant ces événements, le «clic» et les événements associés ne sont pas déclenchés:mouseenter
etmouseleave
semblent être inclus, bien qu'ils ne soient pas spécifiés dans le graphique.Si vous modifiez quoi que ce soit à la suite de ces événements, les événements de clic ne seront pas déclenchés. Cela inclut quelque chose de plus haut dans l'arborescence DOM. Par exemple, cela empêchera les simples clics de fonctionner sur votre site Web avec jQuery:
Edit: Pour clarification, l'
hover
événement de jQuery comprendmouseenter
etmouseleave
. Ceux-ci empêcheront tous les deuxclick
si le contenu est modifié.la source
hover
gestionnaire jquery empêchait unclick
gestionnaire séparé d' être touché - quelle blague!mouseenter
jsbin.com/maseti/5/edit?html,js,outputModernizer de la bibliothèque de détection des fonctionnalités du navigateur inclut une vérification des événements tactiles.
Son comportement par défaut consiste à appliquer des classes à votre élément html pour chaque fonctionnalité détectée. Vous pouvez ensuite utiliser ces classes pour styliser votre document.
Si les événements tactiles ne sont pas activés, Modernizr peut ajouter une classe de
no-touch
:Et puis définissez vos styles de survol avec cette classe:
Vous pouvez télécharger une version personnalisée de Modernizr pour inclure aussi peu ou autant de détections de fonctionnalités que vous en avez besoin.
Voici un exemple de certaines classes qui peuvent être appliquées:
la source
Certains appareils (comme d'autres l'ont dit) ont à la fois des événements tactiles et souris. Le Microsoft Surface, par exemple, dispose d'un écran tactile, d'un trackpad ET d'un stylet qui déclenche en fait des événements de survol lorsqu'il est au-dessus de l'écran.
Toute solution qui se désactive en
:hover
fonction de la présence d'événements «tactiles» affectera également les utilisateurs de Surface (et de nombreux autres appareils similaires). De nombreux nouveaux ordinateurs portables sont tactiles et répondront aux événements tactiles - la désactivation du survol est donc une très mauvaise pratique.C'est un bogue dans Safari, il n'y a absolument aucune justification à ce comportement terrible. Je refuse de saboter les navigateurs non iOS à cause d'un bug dans iOS Safari qui est apparemment là depuis des années. J'espère vraiment qu'ils corrigent ce problème pour iOS8 la semaine prochaine, mais en attendant ....
Ma solution :
Certains ont déjà suggéré d'utiliser Modernizr, enfin Modernizr vous permet de créer vos propres tests. Ce que je fais essentiellement ici, c'est «faire abstraction» de l'idée d'un navigateur qui prend
:hover
en charge un test Modernizr que je peux utiliser dans tout mon code sans codage en durif (iOS)
.Ensuite, le css devient quelque chose comme ça
Ce test échouera et désactivera le rollover uniquement sur iOS.
La meilleure partie d'une telle abstraction est que si je trouve que cela casse sur un certain Android ou s'il est corrigé dans iOS9, je peux simplement modifier le test.
la source
html:not(.no-hover) .category:hover { ...
L'ajout de la bibliothèque FastClick à votre page entraînera la transformation de tous les taps sur un appareil mobile en événements de clic (quel que soit l'endroit où l'utilisateur clique), il devrait donc également résoudre le problème de survol sur les appareils mobiles. J'ai édité votre violon à titre d'exemple: http://jsfiddle.net/FvACN/8/ .
Incluez simplement la bibliothèque fastclick.min.js sur votre page et activez via:
En plus, cela supprimera également le retard ennuyeux de 300 ms onClick dont souffrent les appareils mobiles.
Il y a quelques conséquences mineures à l'utilisation de FastClick qui peuvent ou peuvent ne pas être importantes pour votre site:
la source
Une meilleure solution, sans JS, classe css et vérification de la fenêtre: vous pouvez utiliser les fonctionnalités d'Interaction Media (Media Queries Level 4)
Comme ça:
iOS Safari le prend en charge
En savoir plus: https://www.jonathanfielding.com/an-introduction-to-interaction-media-features/
la source
Il existe essentiellement trois scénarios:
:hover
:hover
élémentsLa réponse acceptée à l'origine fonctionne très bien si seuls les deux premiers scénarios sont possibles, où un utilisateur dispose d' un pointeur ou d'un écran tactile. C'était courant lorsque le PO a posé la question il y a 4 ans. Plusieurs utilisateurs ont souligné que les appareils Windows 8 et Surface rendent le troisième scénario plus probable.
La solution iOS au problème de ne pas pouvoir survoler les appareils à écran tactile (comme détaillé par @Zenexer) est intelligente, mais peut entraîner un mauvais comportement du code simple (comme indiqué par l'OP). La désactivation du survol uniquement pour les appareils à écran tactile signifie que vous devrez toujours coder une alternative conviviale pour l'écran tactile. Détecter quand un utilisateur a à la fois le pointeur et l'écran tactile brouille encore plus les eaux (comme expliqué par @Simon_Weaver).
À ce stade, la solution la plus sûre consiste à éviter d'utiliser
:hover
comme seul moyen pour un utilisateur d'interagir avec votre site Web. Les effets de survol sont un bon moyen d'indiquer qu'un lien ou un bouton peut être actionné, mais un utilisateur ne devrait pas être obligé de survoler un élément pour effectuer une action sur votre site Web.Repenser la fonctionnalité de «survol» avec les écrans tactiles à l'esprit a une bonne discussion sur les approches UX alternatives. Les solutions apportées par la réponse comprennent:
À l'avenir, ce sera probablement la meilleure solution pour tous les nouveaux projets. La réponse acceptée est probablement la deuxième meilleure solution, mais assurez-vous de tenir compte des appareils qui ont également des dispositifs de pointeur. Veillez à ne pas éliminer les fonctionnalités lorsqu'un appareil dispose d'un écran tactile juste pour contourner le
:hover
piratage d'iOS .la source
La version JQuery dans votre .css utilise .no-touch .my-element: hover pour toutes vos règles de survol incluent JQuery et le script suivant
Puis dans la balise body, ajoutez class = "no-touch" ontouchstart = "removeHoverState ()"
dès que l'ontouchstart déclenche la classe pour tous les états de survol est supprimée
la source
Au lieu de n'avoir que des effets de survol lorsque le toucher n'est pas disponible, j'ai créé un système pour gérer les événements tactiles et cela a résolu le problème pour moi. Tout d'abord, j'ai défini un objet pour tester les événements "tap" (équivalent à "click").
Ensuite, dans mon gestionnaire d'événements, je fais quelque chose comme ce qui suit:
la source
Merci @Morgan Cheng pour la réponse, mais j'ai légèrement modifié la fonction JS pour obtenir le " touchstart " (code tiré de la réponse @Timothy Perez ), cependant, vous avez besoin de jQuery 1.7+ pour cela
la source
Compte tenu de la réponse fournie par Zenexer, un modèle qui ne nécessite aucune balise HTML supplémentaire est:
Cette méthode déclenche le survol de la souris en premier, le clic en second.
la source
Je suis d'accord que la désactivation du survol pour le toucher est la voie à suivre.
Cependant, pour vous éviter d'avoir à réécrire votre css, enveloppez simplement tous les
:hover
éléments dans@supports not (-webkit-overflow-scrolling: touch) {}
la source
Pour ceux qui ont des cas d'utilisation courants de désactivation d'
:hover
événements sur iOS Safari, le moyen le plus simple consiste à utiliser une requête multimédia de largeur minimale pour vos:hover
événements qui reste au-dessus de la largeur d'écran des appareils que vous évitez. Exemple:la source
Regardez la taille de l'écran ...
la source
voici le code dans lequel vous voudrez le placer
la source