web-dev-qa-db-fra.com

Pourquoi/quand dois-je appuyer deux fois pour déclencher un clic sur iOS

Ok j'ai l'impression d'être fou ...

Je regarde Mobile Safari sur iOs 6.0. Je n'arrive pas à établir de rime ou de raison de cliquer sur un élément pour déclencher un clic. Dans de nombreux cas, il me semble que je dois appuyer une fois pour déclencher un survol, puis à nouveau pour déclencher un clic.

La spécification Mobile Safari indique: "... Le flux d'événements générés par les gestes à un ou à deux doigts est conditionnel selon que l'élément sélectionné est cliquable ou défilable ... Un élément cliquable est un un lien, un élément de formulaire, une zone de carte graphique ou tout autre élément avec des gestionnaires de déplacement de souris, de souris, de souris ou de clic ... À cause de ces différences, vous pourriez avoir besoin de changer certains de vos éléments en éléments cliquables ...

Il ajoute que le développeur "... ajoute un gestionnaire factice onclick, onclick =" void (0) ", de sorte que Safari sur iOS reconnaisse l'élément span comme un élément cliquable."

Cependant, mes tests ont montré que ces déclarations étaient fausses.

JsFiddle: http://jsfiddle.net/6Ymcy/1/

html

<div id="plain-div" onclick="void(0)">Plain Div</div>

js

document.getElementById('plain-div').addEventListener('click', function() {
   alert('click'); 
});

Essayez de toucher l'élément sur un iPad. Rien ne se passe

Mais je m'égare. Ce qui est important pour moi, c'est de trouver la question suivante:

Quels sont les critères qui déterminent exactement quand un clic sur un élément déclenchera un événement 'clic' au premier tap? Par opposition à déclencher un événement "survol" sur le premier tap et un événement "clic" sur le second tap.

Lors de mes tests, les éléments d'ancrage sont les seuls éléments permettant de déclencher un clic sur le premier tap puis de manière occasionnelle et incohérente.

Voici où je commence à me sentir fou. J'ai parcouru l'internet de très loin et je n'ai pratiquement rien trouvé à ce sujet. Est ce juste moi?! Est-ce que quelqu'un sait où des discussions ont eu lieu sur les critères de double frappe et/ou sur une approche permettant de gérer ces limitations?

Je suis heureux de répondre aux questions/demandes. 

Merci!

29
user2383672

J'ai eu le même problème. La solution la plus simple consiste à ne pas lier l'événement 'mouseenter' sous iOS (ni à aucune plate-forme cible à activation tactile). Si cela n'est pas lié, l'événement de survol ne sera pas déclenché et le déclic sera déclenché au premier tap.

10

iOS déclenchera l'événement de survol si un élément est "display: none;" à l'état normal et "display: block;" ou inline-block on: survolez.

7
noahott

J'avais ce problème en utilisant Bootstrap, et j'ai découvert que le coupable était l'info-bulle. Supprimez l'info-bulle du bouton et vous n'avez plus besoin de la toucher deux fois.

3
sandre89

Il est également intéressant de mentionner que la pseudo-classe ': hover' peut empêcher le déclenchement de l'événement 'clic'.

Comme dans les navigateurs mobiles, un clic est parfois utilisé pour remplacer l'action de survol (par exemple pour afficher le menu déroulant), ils peuvent déclencher un état de survol artificiel au premier clic, puis gérer le clic sur le second.

Voir https://css-tricks.com/annoying-mobile-double-tap-link-issue/ pour des explications détaillées et des exemples.

2
everyonesdesign

J'ai résolu ce problème en détectant d'abord s'il s'agissait d'un iphone, puis en liant l'événement mouseup à la fonction que j'essayais d'appeler.

if ((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i))){ 
    $('foo').on('mouseup', function(){
        ...
    }
}

J'ai essayé d'autres événements mais mouseup semblait mieux fonctionner. D'autres événements tels que touchend se déclenchaient même si l'utilisateur essayait de faire défiler. Mouseup ne semble pas se faire virer si vous faites glisser votre doigt après avoir touché.

Crédit David Walsh (et ESPN) pour la détection de l'iPhone. http://davidwalsh.name/detect-iphone

1
Frank

ma solution a été de supprimer l'état: hover du css, et quand vous y réfléchissez, les navigateurs mobiles ne devraient pas avoir: hover state, car il n'y a pas de survol .. 

si vous souhaitez conserver l'état de survol sur le bureau, vous pouvez utiliser la requête multimédia, comme suit:

.button {
    background: '#000'
}

@media (min-width: 992px) {
    .button:hover {
        background: '#fff'
    }
}
0
Or Bachar

J'étais sur Google pour voir si je pouvais vous aider et trouver cette partie de code. Essayez de le modifier à votre goût et voyez si vous pouvez faire ce que vous essayez. Si vous avez des difficultés à le comprendre, faites-le moi savoir et je développerai davantage. Theres aussi plus ici où je l'ai trouvé

Fonction de survol Jquery et cliquer sur la tablette

$('clickable_element').live("touchstart",function(e){
    if ($(this).data('clicked_once')) {
        // element has been tapped (hovered), reset 'clicked_once' data flag and return true
        $(this).data('clicked_once', false);
        return true;
    } else {
        // element has not been tapped (hovered) yet, set 'clicked_once' data flag to true
        e.preventDefault();
        $(this).trigger("mouseenter"); //optional: trigger the hover state, as preventDefault(); breaks this.
        $(this).data('clicked_once', true);
    }
});
0
Aaron Russell

Vous avez besoin de @media (hover) { /* Your styles */ }

Autant que je sache, ce problème sous diverses formes est toujours présent. 

En 2019, la plupart des cas ci-dessus, sinon tous, peuvent désormais être résolus à l'aide de une solution uniquement CSS ... mais il faudra toutefois procéder à une refactorisation de la feuille de style.

label {
  opacity:0.6  
}

label input[type=radio]:checked+span {
  opacity:1
}

.myClass::before { } /* Leave me empty to catch all browsers */

a:link { color: blue }
a:visited { color: purple }
a:hover { } /* Leave me empty to catch all browsers */
a:active { font-weight: bold }



/* Your styles */
@media (hover) {
  a:hover { color: red }

  .myClass::before { background: black }

  label:hover {
    opacity:0.8
  }
}

Vous pouvez lire plus en détail ici pourquoi Fastclick, :pseudo, <span>, le ciblage des résolutions "de bureau" et first tap is hover and second tap is click sont tous corrigés avec @media (hover): https://css-tricks.com/annoying-mobile-double-tap-link- problème/

:hover n'offre pas la clarté qu'il avait auparavant en matière de saisie au stylet. Les ordinateurs de bureau tactiles et mobiles interprètent la notion de manière disparate.

0
urbanaut

L'affichage: aucun; La solution mentionnée ci-dessus fonctionne sur iOS (pas encore testée avant la 9.3.5), mais pas sur Android.

Une solution de type «hacky css» consiste à masquer le lien sous l’élément à l’aide d’un index z moins et à l’ajouter à un indice z positif: au survol ou au premier contact (avec un léger retard de transition). Je suppose que l'on pourrait obtenir le même résultat avec une traduction CSS au lieu de z-index. Fonctionne sur iOS et Android.

De cette façon, vous pouvez afficher un effet de survol sur un lien sur un périphérique à écran tactile lors du premier toucher sans activer l'URL jusqu'à un second contact.

0
peterh