Ich habe einige CSS-Menüs auf meiner Website, die mit :hover
(ohne js) erweitert werden.
Dies funktioniert auf iDevices halb unterbrochen. Wenn Sie beispielsweise auf tippen, wird die :hover
Regel aktiviert und das Menü erweitert. Wenn Sie jedoch auf eine andere Stelle tippen, wird das nicht entfernt :hover
. Auch wenn sich innerhalb des Elements ein Link befindet :hover
, der bearbeitet wird, müssen Sie zweimal tippen, um den Link zu aktivieren (erster Tap-Trigger :hover
, zweiter Tap-Trigger-Link).
Ich habe es geschafft, dass die Dinge auf dem iPhone gut funktionieren, indem ich das touchstart
Ereignis gebunden habe .
Das Problem ist, dass mobile Safari manchmal immer noch die :hover
Regel aus dem CSS anstelle meiner touchstart
Ereignisse auslöst !
Ich weiß, dass dies das Problem ist, denn wenn ich alle :hover
Regeln manuell im CSS deaktiviere , funktioniert die mobile Safari hervorragend (aber normale Browser funktionieren offensichtlich nicht mehr).
Gibt es eine Möglichkeit, :hover
Regeln für bestimmte Elemente dynamisch "abzubrechen" , wenn sich der Benutzer auf einer mobilen Safari befindet?
Sehen und vergleichen Sie das iOS-Verhalten hier: http://jsfiddle.net/74s35/3/ Hinweis: Nur einige CSS-Eigenschaften lösen das Zwei-Klick-Verhalten aus, z. B. Anzeige: keine; aber nicht Hintergrund: rot; oder Textdekoration: unterstreichen;
quelle
Antworten:
Ich fand, dass ": hover" in iPhone / iPad Safari nicht vorhersehbar ist. Tippen Sie manchmal auf ein Element, um dieses Element ": hover" zu machen, während es manchmal zu anderen Elementen wechselt.
Zur Zeit habe ich nur eine "No-Touch" -Klasse am Körper.
Und haben Sie alle CSS-Regeln mit ": hover" unter ".no-touch":
Irgendwo auf der Seite habe ich Javascript, um die berührungslose Klasse aus dem Körper zu entfernen .
Das sieht nicht perfekt aus, funktioniert aber trotzdem.
quelle
:hover
ist hier nicht das Problem. Safari für iOS folgt einer sehr merkwürdigen Regel. Es feuertmouseover
undmousemove
zuerst; Wenn sich während dieser Ereignisse etwas ändert, werden 'Klick' und verwandte Ereignisse nicht ausgelöst:mouseenter
undmouseleave
scheinen enthalten zu sein, obwohl sie nicht in der Tabelle angegeben sind.Wenn Sie aufgrund dieser Ereignisse Änderungen vornehmen, werden Klickereignisse nicht ausgelöst. Dazu gehört etwas weiter oben im DOM-Baum. Dies verhindert beispielsweise, dass einzelne Klicks mit jQuery auf Ihrer Website funktionieren:
Bearbeiten: Zur Verdeutlichung enthält jQuerys
hover
Ereignismouseenter
undmouseleave
. Beides verhindert,click
dass Inhalte geändert werden.quelle
hover
Handler verhinderte, dass ein separaterclick
Handler getroffen wurde - was für ein Witz!mouseenter
KlickereignisDie Browser-Feature-Erkennungsbibliothek Modernizer enthält eine Überprüfung auf Berührungsereignisse.
Standardmäßig werden für jedes erkannte Feature Klassen auf Ihr HTML-Element angewendet. Sie können diese Klassen dann verwenden, um Ihr Dokument zu formatieren.
Wenn Touch-Ereignisse nicht aktiviert sind, kann Modernizr eine Klasse hinzufügen
no-touch
:Und dann erweitern Sie Ihre Schwebestile mit dieser Klasse:
Sie können einen benutzerdefinierten Modernizr-Build herunterladen der so wenige oder so viele Funktionserkennungen enthält, wie Sie benötigen.
Hier ist ein Beispiel für einige Klassen, die angewendet werden können:
quelle
Einige Geräte (wie andere bereits gesagt haben) haben sowohl Berührungs- als auch Mausereignisse. Das Microsoft Surface verfügt beispielsweise über einen Touchscreen, ein Trackpad UND einen Stift, der tatsächlich Schwebeereignisse auslöst, wenn er über dem Bildschirm bewegt wird.
Jede deaktivierende Lösung
:hover
aufgrund von Berührungsereignissen sich auch auf Surface-Benutzer (und viele andere ähnliche Geräte) aus. Viele neue Laptops sind berührungsempfindlich und reagieren auf Berührungsereignisse. Daher ist das Deaktivieren des Schwebens eine sehr schlechte Vorgehensweise.Dies ist ein Fehler in Safari, es gibt absolut keine Rechtfertigung für dieses schreckliche Verhalten. Ich weigere mich, Nicht-iOS-Browser wegen eines Fehlers in iOS Safari zu sabotieren, der anscheinend seit Jahren vorhanden ist. Ich hoffe wirklich, dass sie dies nächste Woche für iOS8 beheben, aber in der Zwischenzeit ...
Meine Lösung :
Einige haben bereits vorgeschlagen, Modernizr zu verwenden. Mit Modernizr können Sie Ihre eigenen Tests erstellen. Grundsätzlich abstrahiere ich hier die Idee eines Browsers, der
:hover
einen Modernizr-Test unterstützt, den ich im gesamten Code ohne Hardcodierung verwenden kannif (iOS)
.Dann wird das CSS so etwas
Nur unter iOS schlägt dieser Test fehl und deaktiviert den Rollover.
Der beste Teil einer solchen Abstraktion ist, dass ich den Test einfach ändern kann, wenn ich finde, dass er auf einem bestimmten Android kaputt geht oder wenn er in iOS9 behoben ist.
quelle
html:not(.no-hover) .category:hover { ...
Durch Hinzufügen der FastClick-Bibliothek zu Ihrer Seite werden alle Taps auf einem mobilen Gerät in Klickereignisse umgewandelt (unabhängig davon, wo der Benutzer klickt). Daher sollte das Hover-Problem auch auf mobilen Geräten behoben werden. Ich habe Ihre Geige als Beispiel bearbeitet: http://jsfiddle.net/FvACN/8/ .
Fügen Sie einfach die Bibliothek fastclick.min.js in Ihre Seite ein und aktivieren Sie sie über:
Als Nebeneffekt wird auch die lästige onClick-Verzögerung von 300 ms beseitigt, unter der mobile Geräte leiden.
Die Verwendung von FastClick hat einige geringfügige Konsequenzen, die für Ihre Website möglicherweise von Bedeutung sind oder nicht:
quelle
Eine bessere Lösung ohne JS-, CSS-Klassen- und Ansichtsfensterprüfung: Sie können Interaction Media Features (Media Queries Level 4) verwenden.
So was:
iOS Safari unterstützt es
Weitere Informationen zu: https://www.jonathanfielding.com/an-introduction-to-interaction-media-features/
quelle
Grundsätzlich gibt es drei Szenarien:
:hover
:hover
Elemente aktivierenDie ursprünglich akzeptierte Antwort funktioniert hervorragend, wenn nur die ersten beiden Szenarien möglich sind, in denen ein Benutzer entweder einen Zeiger oder einen Touchscreen hat. Dies war üblich, als das OP die Frage vor 4 Jahren stellte. Mehrere Benutzer haben darauf hingewiesen, dass Windows 8- und Surface-Geräte das dritte Szenario wahrscheinlicher machen.
Die iOS-Lösung für das Problem, nicht auf Touchscreen-Geräten schweben zu können (wie von @Zenexer beschrieben), ist clever, kann jedoch dazu führen, dass sich einfacher Code schlecht verhält (wie vom OP angegeben). Wenn Sie den Hover nur für Touchscreen-Geräte deaktivieren, müssen Sie weiterhin eine Touchscreen-freundliche Alternative codieren. Das Erkennen, wenn ein Benutzer sowohl einen Zeiger als auch einen Touchscreen hat, trübt das Wasser weiter (wie von @Simon_Weaver erläutert).
Zu diesem Zeitpunkt besteht die sicherste Lösung darin, die Verwendung
:hover
als einzige Möglichkeit zu vermeiden, mit der ein Benutzer mit Ihrer Website interagieren kann. Hover-Effekte sind eine gute Möglichkeit, um anzuzeigen, dass ein Link oder eine Schaltfläche umsetzbar ist. Ein Benutzer sollte jedoch nicht verpflichtet sein, ein Element zu bewegen, um eine Aktion auf Ihrer Website auszuführen.Das Überdenken der Hover-Funktionalität unter Berücksichtigung von Touchscreens bietet eine gute Diskussion über alternative UX-Ansätze. Die Lösungen, die die Antwort dort bietet, umfassen:
In Zukunft wird dies wahrscheinlich die beste Lösung für alle neuen Projekte sein. Die akzeptierte Antwort ist wahrscheinlich die zweitbeste Lösung. Achten Sie jedoch darauf, Geräte zu berücksichtigen, die auch Zeigergeräte haben. Achten Sie darauf, die Funktionalität nicht zu beeinträchtigen, wenn ein Gerät über einen Touchscreen verfügt, um den
:hover
Hack von iOS zu umgehen.quelle
Die JQuery-Version in Ihrem CSS verwendet .no-touch .my-element: hover für alle Ihre Hover-Regeln enthält JQuery und das folgende Skript
Fügen Sie dann im Body-Tag class = "no-touch" ontouchstart = "removeHoverState ()" hinzu.
Sobald der ontouchstart ausgelöst wird, wird die Klasse für alle Schwebezustände entfernt
quelle
Anstatt nur Schwebeeffekte zu haben, wenn keine Berührung verfügbar ist, habe ich ein System zur Behandlung von Berührungsereignissen erstellt, das das Problem für mich gelöst hat. Zuerst habe ich ein Objekt zum Testen auf "Tap" -Ereignisse (entspricht "Klick") definiert.
Dann mache ich in meinem Event-Handler so etwas wie das Folgende:
quelle
Vielen Dank an @Morgan Cheng für die Antwort. Ich habe jedoch die JS-Funktion leicht geändert, um den " Touchstart " (Code aus der Antwort von @Timothy Perez ) zu erhalten. Dafür benötigen Sie jedoch jQuery 1.7+
quelle
Angesichts der Antwort von Zenexer lautet ein Muster, für das keine zusätzlichen HTML-Tags erforderlich sind:
Diese Methode löst zuerst den Mouseover und dann den Klick aus.
quelle
Ich bin damit einverstanden, dass das Deaktivieren von Hover for Touch der richtige Weg ist.
Um sich jedoch die Mühe zu ersparen, Ihr CSS neu zu schreiben, wickeln Sie einfach alle
:hover
Elemente ein@supports not (-webkit-overflow-scrolling: touch) {}
quelle
Für Benutzer mit häufigem Anwendungsfall zum Deaktivieren von
:hover
Ereignissen in iOS Safari besteht die einfachste Möglichkeit darin, eine Medienabfrage mit minimaler Breite für Ihre:hover
Ereignisse zu verwenden, die über der Bildschirmbreite der Geräte liegt, die Sie vermeiden. Beispiel:quelle
Schauen Sie sich einfach die Bildschirmgröße an ....
quelle
Hier ist der Code, in den Sie ihn einfügen möchten
quelle