115 votes

La pseudo-classe :active ne fonctionne pas dans safari mobile

Dans Webkit sur iPhone/iPad/iPod, le fait de spécifier le style d'une pseudo-classe :active pour un fichier de type <a> ne se déclenche pas lorsque vous tapez sur l'élément. Comment faire pour qu'elle se déclenche ? Exemple de code :

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

249voto

wilsonpage Points 5495
<body ontouchstart="">
    ...
</body>

Appliqué une seule fois, par opposition à chaque élément de bouton, cela semble réparer tous les boutons de la page. Vous pouvez également utiliser cette petite bibliothèque JS appelée ' Fastclick '. Il accélère les événements de clic sur les appareils tactiles et prend en charge ce problème également.

22 votes

N'est-il pas suffisant d'ajouter simplement ontouchstart sans le ="" ? (HTML5)

2 votes

Pour les futurs lecteurs, j'ai posté une démo ici : http://jsbin.com/EjiWILe/3/ . Vérifiez la fonctionnalité de votre appareil iOS.

7 votes

Pouvez-vous expliquer pourquoi vous avez appliqué un écouteur vide à body ? Comment cela fonctionne-t-il ?

65voto

user128216 Points 702

Comme d'autres réponses l'ont indiqué, iOS Safari ne déclenche pas l'alerte de l'utilisateur. :active à moins qu'un événement tactile ne soit attaché à l'élément, mais jusqu'à présent ce comportement a été "magique". Je suis tombé sur ce petit texte sur le site Bibliothèque du développeur Safari qui l'explique (c'est moi qui souligne) :

Vous pouvez également utiliser le -webkit-tap-highlight-color La propriété CSS, combinée à la définition d'un événement tactile, permet de configurer les boutons pour qu'ils se comportent comme sur le bureau. Sur iOS, les événements liés à la souris sont envoyés si rapidement que l'état abaissé ou actif n'est jamais reçu. Par conséquent, le :active 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 vous appuyez sur le bouton et le maintenez enfoncé sur iOS, le bouton prend la couleur spécifiée sans que la couleur grise transparente qui l'entoure n'apparaisse.

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

À mon avis, c'est un comportement défectueux, qui remonte probablement à l'époque où le web "mobile" était pratiquement inexistant (jetez un coup d'œil aux captures d'écran sur la page liée pour voir ce que je veux dire), et où tout était orienté vers la souris. Il est intéressant de noter que d'autres navigateurs mobiles plus récents, comme Android, affichent très bien le pseudo-état `:active' sur le toucher, sans aucun bidouillage comme celui qui est nécessaire pour iOS.

(Remarque : si vous souhaitez utiliser vos propres styles personnalisés sur iOS, vous pouvez également désactiver la boîte translucide grise par défaut qu'iOS utilise à la place de l'icône de l'utilisateur. :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érimentations, la solution attendue consistant à fixer un ontouchstart sur l'événement <body> élément qui todo touch events then bubble to ne fonctionne pas complètement. Si l'élément est visible dans la fenêtre d'affichage au moment du chargement de la page, cela fonctionne bien, mais le fait de faire défiler la page vers le bas et de toucher un élément qui n'est pas dans la fenêtre d'affichage ne fonctionne pas. no déclencher le :active pseudo-état comme il se doit. Ainsi, 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 qui remonte jusqu'au corps (en utilisant jQuery) :

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

Cependant, je ne suis pas conscient des implications de cette mesure sur les performances, alors méfiez-vous.


EDITAR: Cette solution présente un grave défaut : le simple fait de toucher un élément pendant le défilement de la page active la fonction :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 est défilée. À la lumière de ceci, je suggère d'utiliser ceci seulement sur les éléments sélectionnés. Dans mon cas, je développe une application Web destinée à être utilisée sur le terrain, qui consiste essentiellement en une liste de boutons permettant de naviguer dans les pages et de soumettre des actions. Comme la page entière est constituée de boutons dans certains cas, cela ne fonctionnera pas pour moi. Vous pouvez toutefois définir le paramètre :hover pseudo-état pour le remplacer. Après avoir désactivé la boîte grise par défaut, cela fonctionne parfaitement.

40voto

Jesse Rusak Points 33702

Ajoutez un gestionnaire d'événement pour ontouchstart dans votre balise <a>. Cela permet à la CSS de fonctionner comme par magie.

<a ontouchstart="">Click me</a>

3 votes

Désolé, c'est une vieille réponse, mais pourquoi cela fonctionne-t-il ? Le terme "par magie" ne me dérange pas, mais si vous pouviez expliquer pourquoi cela fonctionne, j'aimerais beaucoup en savoir plus.

1 votes

@mhulse J'aimerais aussi savoir pourquoi.

0 votes

Ha ! Nous sommes dans le même bateau. Je vais essayer de faire quelques recherches et de poster ici un lien vers les documents (semi-)officiels sur le sujet. J'adore que cette technique fonctionne, je me demande juste pourquoi ?

7voto

dhqvinh Points 179

Ce site fonctionne pour moi :

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

Remarque : si vous utilisez cette astuce, il est également utile de supprimer la couleur de mise en évidence par défaut que Mobile Safari applique en utilisant la règle CSS suivante.

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

6voto

Ali Points 18740

En date 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 qui étaient visibles au chargement de la page.

Cependant, en ajoutant :

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

à la head fonctionne comme je le souhaite, avec l'inconvénient que maintenant, tous les événements tactiles pendant le défilement déclenchent également la commande :active pseudo-état sur les éléments touchés. (Si c'est un problème pour vous, vous pourriez considérer FighterJet's :hover solution de rechange).

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