web-dev-qa-db-fra.com

: la pseudo-classe active ne fonctionne pas dans le safari mobile

Dans Webkit sur iPhone/iPad/iPod, la définition du style d'une pseudo-classe active pour une balise <a> Ne se déclenche pas lorsque vous appuyez sur l'élément. Comment puis-je obtenir cela pour déclencher? Exemple de code:

<style> 
a:active { 
    background-color: red;
}
</style>
<!-- snip -->
<a href="#">Click me</a>
96
Jesse Rusak
<body ontouchstart="">
    ...
</body>

Appliqué une seule fois, contrairement à chaque élément de bouton qui semblait corriger tous les boutons de la page. Sinon, vous pouvez utiliser cette petite bibliothèque JS appelée ' Fastclick '. Il accélère les événements de clic sur les appareils tactiles et prend également en charge ce problème.

223
wilsonpage

Comme d'autres réponses l'ont indiqué, iOS Safari ne déclenche pas le :active pseudo-classe sauf si un événement tactile est attaché à l'élément, mais jusqu'à présent, ce comportement était "magique". Je suis tombé sur ce petit texte de présentation sur le Safari Developer Library qui l'explique (à moi de souligner):

Vous pouvez aussi utiliser le -webkit-tap-highlight-color Propriété CSS associée à la définition d’un événement tactile pour que les boutons se comportent de manière similaire au bureau. Sur iOS, les événements de souris sont envoyés si rapidement que l'état inactif ou actif n'est jamais reçu. Par conséquent, le :active Le pseudo-état est déclenché uniquement lorsqu'un événement tactile est défini sur l'élément HTML, par exemple, lorsque ontouchstart est défini sur l'élément comme suit:

<button class="action" ontouchstart=""
        style="-webkit-tap-highlight-color: rgba(0,0,0,0);">
    Testing Touch on iOS
</button>

Désormais, lorsque le bouton est appuyé et maintenu sur iOS, il passe à la couleur spécifiée sans que la couleur gris transparent qui l'entoure n'apparaisse.

En d'autres termes, définir un événement ontouchstart (même s'il est vide) indique explicitement au navigateur de réagir aux événements tactiles.

À mon avis, ce comportement est défectueux et remonte probablement à l'époque où le Web "mobile" était quasiment inexistant (regardez ces captures d'écran sur la page liée pour voir ce que je veux dire), et tout était orienté à la souris. Il est intéressant de noter que d'autres navigateurs mobiles plus récents, tels qu'Android, affichent très bien le pseudo-état `: actif 'au toucher, sans aucun piratage similaire à celui nécessaire pour iOS.

(Remarque: si vous souhaitez utiliser vos propres styles personnalisés sur iOS, vous pouvez également désactiver la zone gris translucide par défaut qu'IOS utilise à la place du :active pseudo-état en utilisant le -webkit-tap-highlight-color Propriété CSS, comme expliqué dans la même page liée ci-dessus.)


Après quelques expériences, la solution attendue consiste à définir un événement ontouchstart sur le <body> élément qui tous événements tactiles puis bulle à ne fonctionne pas complètement. Si l'élément est visible dans la fenêtre lors du chargement de la page, cela fonctionne correctement, mais le fait de faire défiler l'écran vers le bas et de cliquer sur un élément qui n'était pas dans la fenêtre ne = pas déclenche le :active pseudo-état comme il se doit. Donc, au lieu de

<!DOCTYPE html>
<html><body ontouchstart></body></html>

attachez l'événement à tous les éléments au lieu de compter sur l'événement remontant jusqu'au corps (à l'aide de jQuery):

$('body *').on('touchstart', function (){});

Cependant, je ne suis pas au courant des conséquences pour la performance, alors méfiez-vous.


EDIT: Il y a un défaut sérieux à cette solution: même si vous touchez un élément tout en faisant défiler la page, le :active pseudo-état. La sensibilité est trop forte. Android résout ce problème en introduisant un très petit délai avant l'affichage de l'état, qui est annulé si la page défile. En conséquence, je suggère de ne l'utiliser que sur certains éléments. Dans mon cas, Je suis en train de développer une application Web à utiliser sur le terrain, qui consiste en une liste de boutons permettant de naviguer dans les pages et de soumettre des actions. Comme toute la page est constituée de boutons, dans certains cas, cela ne fonctionne pas. cependant, définissez le :hover pseudo-état à remplir pour cela à la place. Après avoir désactivé la zone grise par défaut, cela fonctionne parfaitement.

45
user128216

Ajoutez un gestionnaire d’événements pour ontouchstart dans votre balise <a>. Cela provoque le travail magique de la CSS.

<a ontouchstart="">Click me</a>
39
Jesse Rusak

Ceci fonctionne pour moi:

document.addEventListener("touchstart", function() {},false);

Remarque: si vous suivez cette astuce, il vaut également la peine de supprimer la couleur de frappe/surlignage par défaut que Mobile Safari applique à l'aide de la règle CSS suivante.

html {
    -webkit-tap-highlight-color: rgba(0,0,0,0);
}
7
dhqvinh

À compter du 8 décembre 2016, la réponse acceptée (<body ontouchstart="">...</body>) ne fonctionne pas pour moi sur Safari 10 (iPhone 5s): ce hack ne fonctionne que pour les éléments visibles au chargement de la page.

Cependant, en ajoutant:

<script type='application/javascript'>
  document.addEventListener("touchstart", function() {}, false);
</script>

head fonctionne comme je le veux, mais tous les événements tactiles du défilement déclenchent également le :active pseudo-état sur les éléments touchés. (Si cela vous pose un problème, vous pourriez envisager de FighterJet's:hover solution de contournement.)

4
Ali

Utilisez-vous toutes les pseudo-classes ou seulement celle-ci? Si vous en utilisez au moins deux, assurez-vous qu'ils sont dans le bon ordre ou qu'ils se cassent tous:

a:link
a:visited
a:hover
a:active

..dans cet ordre. En outre, si vous utilisez simplement: active, ajoutez un lien:, même si vous ne le stylez pas.

3
tahdhaze09
//hover for ios
-webkit-tap-highlight-color: #ccc;

Cela fonctionne pour moi, ajoutez à votre CSS sur l'élément que vous souhaitez mettre en évidence.

3
Redeye

J'ai publié un outil qui devrait résoudre ce problème pour vous.

En apparence, le problème semble simple, mais en réalité, le comportement du toucher et du clic doit être personnalisé de manière assez approfondie, y compris des fonctions de délai d’expiration et des tâches telles que "que se passe-t-il lorsque vous faites défiler une liste de liens" ou "que se passe-t-il lorsque vous appuyez sur lien puis sur éloignez la souris/le doigt de la zone active "

Cela devrait résoudre tout en une fois: https://www.npmjs.com/package/active-touch

Vous devrez attribuer vos styles actifs à la classe .active ou choisir votre propre nom de classe. Par défaut, le script fonctionnera avec tous les éléments de lien, mais vous pouvez l'écraser avec votre propre tableau de sélecteurs.

Réactions honnêtes et utiles et contributions très appréciées!

1
dmitrizzle

Une solution consiste à compter sur :target au lieu de :active:

<style> 
a:target { 
    background-color: red;
}
</style>
<!-- snip -->
<a id="click-me" href="#click-me">Click me</a>

Le style sera déclenché lorsque l'ancre est ciblée par l'URL actuelle, qui est robuste, même sur mobile. L'inconvénient est que vous avez besoin d'un autre lien pour effacer l'ancre dans l'URL. Exemple complet:

a:target { 
    background-color: red;
}
<a id="click-me" href="#click-me">Click me</a>
<a id="clear" href="#">Clear</a>
0
wasthishelpful

Pour ceux qui ne veulent pas utiliser le ontouchstart, vous pouvez utiliser ce code

<script>
 document.addEventListener("touchstart", function(){}, true);
</script>
0
Noob Dev