98 votes

Est il possible de forcer ignorer le : hover pseudoclass pour les utilisateurs d’iPhone/iPad ?

J'ai quelques menus css sur mon site qui se développer avec :hover (sans js)

Cela fonctionne dans un semi-broken façon sur les iDevices, par exemple, un robinet qui va activer l' :hover règle et développez le menu, puis en tapant ailleurs ne supprime pas l' :hover. Aussi, si il y a un lien à l'intérieur de l'élément, c'est - :hover'ed, vous devez appuyez deux fois pour activer le lien (appuyez d'abord sur des déclencheurs :hover, deuxième appuyez sur les déclencheurs de lien).

J'ai été en mesure de faire fonctionner les choses bien sur l'iphone par la liaison de l' touchstart événement.

Le problème est que, parfois, le navigateur safari mobile encore choisit de déclencher l' :hover de la règle de la css à la place de mon touchstart événements!

Je sais que c'est le problème, parce que quand j'ai désactiver tous les :hover règles manuellement dans le css, le navigateur safari mobile fonctionne très bien (mais régulière des navigateurs, évidemment, ne le font plus).

Est-il un moyen dynamique d' "annuler" :hover règles pour certains éléments lorsque l'utilisateur est sur le navigateur safari mobile?

Voir et comparer iOS comportement ici: http://jsfiddle.net/74s35/3/ Remarque: seules certaines propriétés css déclencher les deux-cliquez sur le comportement, par exemple display:none; mais pas de background: red; text-decoration: underline;

77voto

Morgan Cheng Points 15101

J'ai trouvé que ":hover" est imprévisible dans l'iPhone/iPad Safari. Parfois, appuyez sur l'élément que l'élément ":hover", bien que parfois, il dérive à d'autres éléments.

Pour le moment, j'ai juste un "no-touch" de la classe au corps.

<body class="yui3-skin-sam no-touch">
   ...
</body>

Et ont toutes les règles CSS avec ":hover" en-dessous ".no-touch":

.no-touch my:hover{
   color: red;
}

Quelque part dans la page, j'ai le javascript pour supprimer no-touch classe de corps.

if ('ontouchstart' in document) {
    Y.one('body').removeClass('no-touch');
}

Cela n'a pas l'air parfait, mais il fonctionne de toute façon.

48voto

Zenexer Points 4192

:hover n'est pas la question ici. Safari pour iOS suit un très étrange à la règle. Il incendies mouseover et mousemove première; si quelque chose est modifié au cours de ces événements, "clic", et les événements connexes de ne pas me faire virer:

Diagram of touch event in iOS

mouseenter et mouseleave semblent être inclus, si elles ne sont pas spécifiées dans le tableau.

Si vous modifiez quelque chose comme une conséquence de ces événements, cliquez sur événements à ne pas me faire virer. Qui comprend quelque chose à un niveau supérieur dans l'arborescence DOM. Par exemple, cela permettra d'éviter de simples clics de travailler sur votre site web avec jQuery:

$(window).on('mousemove', function() {
    $('body').attr('rel', Math.random());
});

Edit: Pour plus de précisions, jQuery hover y mouseenter et mouseleave. Ces permettra à la fois de prévenir click si le contenu est modifié.

18voto

Beau Smith Points 8112

Le navigateur de la fonctionnalité de détection de la bibliothèque Moderniste comporte une case pour les événements tactiles.

C'est le comportement par défaut est d'appliquer les classes de votre élément html pour chaque caractéristique d'être détecté. Vous pouvez ensuite utiliser ces classes pour le style de votre document.

Si les événements tactiles ne sont pas activés Modernizr pouvez ajouter une classe d' no-touch:

<html class="no-touch">

Et puis portée de votre hover styles avec cette classe:

.no-touch a:hover { /* hover styles here */ }

Vous pouvez télécharger une coutume Modernizr construire pour inclure aussi peu ou autant de fonctionnalité de détections que vous en avez besoin.

Voici un exemple de certaines classes qui peuvent être appliquées:

<html class="js no-touch postmessage history multiplebgs
             boxshadow opacity cssanimations csscolumns cssgradients
             csstransforms csstransitions fontface localstorage sessionstorage
             svg inlinesvg no-blobbuilder blob bloburls download formdata">

18voto

Simon_Weaver Points 31141

Certains appareils (comme d'autres l'ont dit) ont à la fois le toucher et les événements de la souris. La Surface de Microsoft, par exemple, a un écran tactile, d'un pavé tactile ET d'un stylet qui soulève placez les événements lorsqu'il est planait au-dessus de l'écran.

Toute solution qui désactive :hover basé sur la présence de "toucher" des événements sera également affecter la Surface des utilisateurs (et de nombreux autres appareils similaires). Beaucoup de nouveaux ordinateurs portables sont en contact et de répondre à toucher les événements - la désactivation de vol stationnaire est une très mauvaise pratique.

C'est un bug dans Safari, il n'y a absolument aucune justification à cette terrible comportement. Je refuse de sabotage non des navigateurs iOS à cause d'un bug dans iOS Safari qui a apparemment été pendant des années. J'espère vraiment qu'ils résoudre ce problème pour iOS8 la semaine prochaine, mais en attendant....

Ma solution:

Certains ont suggéré à l'aide de Modernizr déjà, bien Modernizr vous permet de créer vos propres tests. Ce que je suis fondamentalement en train de faire ici est de "l'abstraction", l'idée d'un navigateur qui prend en charge :hover dans un Modernizr test que je peux utiliser tout au long de mon code sans le coder en dur if (iOS) tout au long de.

 Modernizr.addTest('workinghover', function ()
 {
      // Safari doesn't 'announce' to the world that it behaves badly with :hover
      // so we have to check the userAgent  
      return navigator.userAgent.match(/(iPad|iPhone|iPod)/g) ? false : true;
 });

Puis le css devient quelque chose comme ceci

html.workinghover .rollover:hover 
{
    // rollover css
}

Uniquement sur iOS sera ce test échoue et désactiver le renouvellement.

La meilleure partie de cette abstraction est que si je trouve qu'il se brise sur un certain android ou si elle est fixe dans iOS9 alors je peux juste modifier le test.

16voto

Troy Points 1372

Ajouter le FastClick bibliothèque de votre page sera la cause de tous les robinets sur un appareil mobile sera transformé en cliquez sur événements (indépendamment de l'endroit où l'utilisateur clique), de sorte qu'il devrait également fixer le hover problème sur les appareils mobiles. J'ai édité votre violon comme exemple: http://jsfiddle.net/FvACN/8/.

Il suffit d'inclure les fastclick.min.js lib sur votre page, et de l'activer via:

FastClick.attach(document.body);

D'un autre côté, elle supprime également la fâcheuse 300ms onClick retard que les appareils mobiles souffrent.


Il ya un couple de des conséquences mineures à l'aide de FastClick qui peut ou ne peut pas d'importance pour le site:

  1. Si vous touchez quelque part sur la page, faites défiler vers le haut, faites défiler vers le bas, puis relâchez votre doigt sur la même position exacte que vous avez initialement placé, FastClick s'interpréter que comme un "clic", même si ce n'est évidemment pas. Au moins c'est la façon dont il fonctionne dans la version de FastClick que je suis en train d'utiliser (1.0.0). Quelqu'un peut l'avoir résolu le problème depuis cette version.
  2. FastClick supprime la possibilité pour quelqu'un de "double clic".

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