J'ai quelques sites Web que j'ai construits il y a des temps, qui utilisent des événements de souris jquery ... Je viens de recevoir un iPad et j'ai remarqué que tous les événements de survol de la souris sont traduits en clics ... donc par exemple, je dois faire deux clics au lieu d'un .. (le premier survol, que le clic réel)
existe-t-il une solution de contournement prête à résoudre ce problème? peut-être une commande jquery que je devrais avoir utilisée au lieu de mouseover / out etc. merci!
Réponses:
Je n'ai pas testé cela complètement, mais comme iOS déclenche des événements tactiles, cela pourrait fonctionner, en supposant que vous soyez dans un paramètre jQuery.
L'idée est que Mobile WebKit déclenche un
touchend
événement à la fin d'un tap, donc nous écoutons cela, puis redirigeons le navigateur dès qu'untouchend
événement a été déclenché sur un lien.la source
.on
est préférable à.live
. Après avoir lu cette réponse, j'ai trouvé que changer mon code$('a').on('click touchend', function(e) {...})
fonctionne parfaitement.target="_blank"
il s'ouvrira dans la même fenêtre ET dans une nouvelle fenêtre.Votre question n'est pas tout à fait claire, mais si vous souhaitez simplement éliminer le double clic, tout en conservant l'effet de survol pour la souris, mon conseil est de:
touchstart
etmouseenter
.mouseleave
,touchmove
etclick
.Contexte
Afin de simuler une souris, les navigateurs tels que Webkit mobile déclenchent les événements suivants si un utilisateur touche et relâche un doigt sur l'écran tactile (comme l'iPad) (source: Touch And Mouse sur html5rocks.com):
touchstart
touchmove
touchend
mouseover
mouseenter
mouseover
,mouseenter
oumousemove
modifie le contenu de la page, les événements suivants ne sont jamais déclenchés.mousemove
mousedown
mouseup
click
Il ne semble pas possible de dire simplement au navigateur Web de sauter les événements de la souris.
Pire encore, si un événement mouseover modifie le contenu de la page, l'événement click n'est jamais déclenché, comme expliqué dans Safari Web Content Guide - Handling Events , en particulier la figure 6.4 dans One-Finger Events . Ce qu'est exactement un «changement de contenu» dépendra du navigateur et de la version. J'ai constaté que pour iOS 7.0, un changement de couleur d'arrière-plan n'est pas (ou plus?) Un changement de contenu.
Solution expliquée
Récapituler:
touchstart
etmouseenter
.mouseleave
,touchmove
etclick
.Notez qu'il n'y a aucune action sur
touchend
!Cela fonctionne clairement pour les événements de souris:
mouseenter
etmouseleave
(versions légèrement améliorées demouseover
etmouseout
) sont déclenchés, et ajoutez et supprimez le survol.Si l'utilisateur
click
un lien, l'effet de survol est également supprimé. Cela garantit qu'il est supprimé si l'utilisateur appuie sur le bouton de retour dans le navigateur Web.Cela fonctionne également pour les événements tactiles: sur
touchstart
l'effet de survol est ajouté. Il n'est "" pas "supprimé letouchend
. Il est ajouté à nouveaumouseenter
, et comme cela n'entraîne aucun changement de contenu (il a déjà été ajouté), l'click
événement est également déclenché et le lien est suivi sans que l'utilisateur ait besoin de cliquer à nouveau!Le délai de 300 ms qu'un navigateur a entre un
touchstart
événement etclick
est effectivement utilisé à bon escient car l'effet de survol sera affiché pendant ce court laps de temps.Si l'utilisateur décide d'annuler le clic, un mouvement du doigt le fera comme d'habitude. Normalement, c'est un problème car aucun
mouseleave
événement n'est déclenché et l'effet de survol reste en place. Heureusement, cela peut facilement être résolu en supprimant l'effet de survoltouchmove
.C'est tout!
Notez qu'il est possible de supprimer le délai de 300 ms, par exemple à l'aide de la bibliothèque FastClick , mais cela est hors de portée pour cette question.
Solutions alternatives
J'ai trouvé les problèmes suivants avec les alternatives suivantes:
touchend
: Cela suivra incorrectement le lien, même si l'utilisateur voulait uniquement faire défiler ou zoomer, sans l'intention de cliquer réellement sur le lien.touchend
qui est utilisée comme condition if dans les événements de souris suivants pour empêcher les changements d'état à ce moment-là. La variable est réinitialisée dans l'événement de clic. C'est une solution décente si vous ne voulez vraiment pas d'effet de survol sur les interfaces tactiles. Malheureusement, cela ne fonctionne pas si atouchend
est déclenché pour une autre raison et qu'aucun événement de clic n'est déclenché (par exemple, l'utilisateur a fait défiler ou zoomé), et tente ensuite de suivre le lien avec une souris (c'est-à-dire sur un appareil avec à la fois une souris et une interface tactile ).Lectures complémentaires
mouseover
oumousemove
.Voir également Problème de double-clic sur iPad / iPhone et Désactiver les effets de survol sur les navigateurs mobiles .
la source
Il semble qu'il existe une solution CSS après tout. La raison pour laquelle Safari attend une deuxième touche est à cause de l'image d'arrière-plan (ou des éléments) que vous attribuez habituellement à l'événement: hover. S'il n'y en a pas à afficher, vous n'aurez aucun problème. La solution est de cibler la plateforme iOS avec un fichier CSS secondaire (ou un style dans le cas d'une approche JS) qui se substitue: survolez l'arrière-plan pour hériter par exemple et gardez cachés les éléments que vous alliez afficher au survol de la souris:
Voici un exemple de CSS et HTML - un bloc de produit avec une étiquette étoilée au survol de la souris:
HTML:
CSS:
Solution (CSS secondaire):
la source
Pas besoin de faire trop compliqué.
la source
Ce qui a fonctionné pour moi, c'est ce que d'autres ici ont déjà dit:
Ne pas afficher / masquer les éléments au survol ou à la souris (ce qui est l'événement dans mon cas).
Voici ce que dit Apple ( https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html ):
Ainsi, vous pouvez utiliser la solution de @ woop: détecter le userAgent, vérifier s'il s'agit d'un appareil iOS, puis lier l'événement. J'ai fini par utiliser cette technique car elle répond à mes besoins et il est plus logique de ne pas lier les événements de survol lorsque vous ne le souhaitez pas.
Mais ... si vous ne voulez pas jouer avec userAgents et toujours masquer / afficher des éléments sur hover / mousemove, j'ai découvert que vous pouvez le faire en utilisant du javascript natif, comme ceci:
Cela fonctionnera sur la version Desktop et ne fera rien sur la version mobile.
Et pour un peu plus de compatibilité ...
la source
La solution de cduruk a été assez efficace, mais a causé des problèmes sur quelques parties de mon site. Parce que j'utilisais déjà jQuery pour ajouter la classe de survol CSS, la solution la plus simple était de simplement ne pas ajouter la classe de survol CSS sur les appareils mobiles (ou plus précisément, de l'ajouter UNIQUEMENT lorsque PAS sur un appareil mobile).
Voici l'idée générale:
* code réduit à titre illustratif
la source
Je pense qu'il serait sage d'essayer
mouseenter
à la place demouseover
. C'est ce qui est utilisé en interne lors de la liaison.hover(fn,fn)
et c'est généralement ce que vous voulez.la source
J'ai eu les problèmes suivants avec les solutions existantes et j'ai trouvé quelque chose qui semble les résoudre toutes. Cela suppose que vous visez quelque chose de multi-navigateur, multi-appareil et que vous ne voulez pas renifler l'appareil.
Les problèmes que cela résout
En utilisant juste
touchstart
outouchend
:Déclenchement des
mouseover
événements surtouchstart
etmouseout
surtouchmove
a des conséquences moins graves, mais n'interfère avec le comportement du navigateur habituel, par exemple:touchstart
comme unmouseover
, qui estmouseout
édité sur le suivanttouchstart
. Une façon de voir le contenu de la souris dans Android est donc de toucher la zone d'intérêt et de bouger votre doigt, en faisant légèrement défiler la page. Traitertouchmove
commemouseout
casse cela.La solution
En théorie, vous pouvez simplement ajouter un drapeau avec
touchmove
, mais les iPhones déclenchent le touchmove même s'il n'y a pas de mouvement. En théorie, vous pouvez simplement comparer letouchstart
ettouchend
événementpageX
etpageY
mais sur iPhone, il n'y a pastouchend
pageX
oupageY
.Donc, malheureusement, pour couvrir toutes les bases, cela finit par être un peu plus compliqué.
En théorie, il existe des moyens d'obtenir l'heure exacte utilisée pour une impression longue au lieu d'utiliser simplement 1000 comme approximation, mais en pratique, ce n'est pas si simple et il est préférable d'utiliser un proxy raisonnable .
la source
La réponse de MacFreak m'a été extrêmement utile. Voici un code pratique au cas où cela vous aiderait.
PROBLÈME - appliquer touchend signifie que chaque fois que vous faites défiler votre doigt sur un élément, il répond comme si vous l'aviez appuyé, même si vous essayiez simplement de faire défiler.
Je crée un effet avec jQuery qui fait fondre une ligne sous certains boutons pour "mettre en évidence" le bouton survolé. Je ne veux pas que cela signifie que vous devez appuyer deux fois sur le bouton des appareils tactiles pour suivre le lien.
Voici les boutons:
Je veux que le div "menu_underline" disparaisse au passage de la souris et disparaisse au passage de la souris. MAIS je veux que les appareils tactiles puissent suivre le lien en un seul clic, pas deux.
SOLUTION - Voici le jQuery pour le faire fonctionner:
Merci beaucoup pour votre aide sur ce MacFreak.
la source
Je viens de découvrir que cela fonctionne si vous ajoutez un auditeur vide, ne me demandez pas pourquoi, mais je l'ai testé sur iPhone et iPad avec iOS 9.3.2 et cela a bien fonctionné.
la source
Je "pense" que vos liens n'ont pas d'événement onmouseover, où 1 tap active onmouseover et le double tap active le lien. mais idk. Je n'ai pas d'iPad. Je pense que tu dois utiliser des événements gestuels / tactiles.
https://developer.apple.com/documentation/webkitjs
la source
J'ai eu le même problème mais pas sur un appareil tactile. L'événement se déclenche à chaque fois que vous cliquez. Il y a quelque chose à propos de la file d'attente d'événements.
Cependant, ma solution était la suivante: sur l'événement de clic (ou toucher?) Vous définissez une minuterie. Si le lien est à nouveau cliqué dans X ms, vous renvoyez simplement false.
Pour définir la minuterie par élément, vous pouvez utiliser
$.data()
.Cela peut également résoudre le problème @Ferdy décrit ci-dessus.
la source
Si vous utilisez Modernizr, il est très facile d'utiliser Modernizr.touch comme mentionné précédemment.
Cependant, je préfère utiliser une combinaison de tests Modernizr.touch et d'agent utilisateur, juste pour être sûr.
Si vous n'utilisez pas Modernizr, vous pouvez simplement remplacer le
Modernizr.touch
fonction ci-dessus par('ontouchstart' in document.documentElement)
Notez également que le test de l'agent utilisateur iemobile vous donnera une plus large gamme d'appareils mobiles Microsoft détectés que Windows Phone.
la source
Vous pouvez utiliser
click touchend
,exemple:
L'exemple ci-dessus affectera tous les liens sur les appareils tactiles.
Si vous souhaitez cibler uniquement des liens spécifiques, vous pouvez le faire en leur définissant une classe, c'est-à-dire:
HTML:
<a href="example.html" class="prevent-extra-click">Prevent extra click on touch device</a>
Jquery:
À votre santé,
Jeroen
la source
J'ai rencontré une situation similaire où j'avais des événements liés aux états mouseenter / mouseleave / click d'un élément, mais sur un iPhone, l'utilisateur devait double-cliquer sur l'élément pour déclencher d'abord l'événement mouseenter, puis à nouveau pour déclencher l'événement click .
J'ai résolu cela en utilisant une méthode similaire à celle ci-dessus, mais j'ai utilisé le plugin jQuery $ .browser (pour jQuery 1.9>) et ajouté un événement .trigger à l'événement de liaison mouseenter, comme suit:
Le .trigger évite d'avoir à double-cliquer sur l'élément en déclenchant le gestionnaire d'événements .click lors de la saisie de la souris (ou du clic initial) de l'élément lorsqu'il est visualisé sur iPhone ou iPad. Ce n'est peut-être pas la solution la plus élégante, mais cela fonctionne très bien dans mon cas et utilise un plugin que j'avais déjà en place, et m'a obligé à ajouter une seule ligne de code pour que mes événements existants fonctionnent sous ces appareils.
Vous pouvez obtenir le plugin jQuery $ .browser ici: https://github.com/gabceb/jquery-browser-plugin
la source
Juste une amélioration pour éviter la redirection lorsque vous faites glisser votre doigt sur un lien par erreur.
la source
Avec l'inspiration de MacFreak, j'ai mis en place quelque chose qui fonctionne pour moi.
Cette méthode js empêche le survol de coller sur un iPad et empêche le clic de s'enregistrer en deux clics dans certains cas. En CSS, si vous avez des classes: hover psudo dans votre css, changez-les en .hover Par exemple .some-class: hover en .some-class.hover
Testez ce code sur un iPad pour voir comment les méthodes hover css et js se comportent différemment (en effet hover uniquement). Le bouton CSS n'a pas d'alerte de clic sophistiquée. http://jsfiddle.net/bensontrent/ctgr6stm/
la source
Pour que les liens fonctionnent sans interrompre le défilement tactile, j'ai résolu ce problème avec l'événement "tap" de jQuery Mobile:
la source
Je suis trop tard, je sais, mais c'est l'une des solutions de contournement les plus simples que j'ai trouvées:
Cela ne fonctionne pas seulement pour les liens (balises d'ancrage) mais aussi pour d'autres éléments. J'espère que cela t'aides.
la source
Ce court extrait semble fonctionner. Déclenchez l'événement de clic lorsque le lien est tapé:
la source
Aucune de l'autre réponse ne fonctionne pour moi. Mon application a beaucoup d'écouteurs d'événements, de propres cases à cocher et de liens qui ont un auditeur et des liens sans auditeur.
J'utilise ceci:
la source
Cela fonctionne pour moi lorsque vous avez jquery ui dropdown
la source
Évitez de changer le style «d'affichage» à l'intérieur de l'événement css hover. J'avais "display: block" en état de survol. Après avoir retiré ios est allé sur les lignes en un seul clic. Au fait, il semble que les dernières mises à jour IOS aient corrigé cette "fonctionnalité"
la source
Le moyen le plus simple de résoudre le double-clic sur l'iPad consiste à envelopper votre css pour un effet de survol dans une requête multimédia
@media (pointer: fine)
:Le CSS enveloppé dans cette requête multimédia ne s'appliquera que sur le bureau.
L'explication de cette solution est ici https://css-tricks.com/annoying-mobile-double-tap-link-issue/
la source
Vous pouvez vérifier
navigator.userAgent
comme ceci:mais vous devrez vérifier les mûres, les droïdes et les autres appareils à écran tactile. Vous pouvez également lier les survols de souris uniquement si userAgent contient Mozilla, IE, Webkit ou Opera, mais vous devez toujours rechercher certains appareils car le Droid, par exemple, signale sa chaîne userAgent comme:
La chaîne de l'iPhone est similaire. Si vous recherchez uniquement iPhone, iPod, iPad, Android et Blackberry, vous pourriez obtenir la majorité des ordinateurs de poche, mais pas tous.
la source
Faites simplement une requête multimédia CSS qui exclut les tablettes et les appareils mobiles et placez le survol. Vous n'avez pas vraiment besoin de jQuery ou de JavaScript pour cela.
Et assurez-vous de l'ajouter à votre tête HTML pour vous assurer qu'il calcule avec les pixels réels et non la résolution.
la source