Ein Klick in iOS Safari löst einen „Hover-Status“ auf dem Element aus, auf das Sie getippt haben

Lesezeit: 7 Minuten

Benutzer-Avatar
Romellem

Wenn ich unter iOS Safari 11 eine <div> über einem Element positioniert, das ein hat :hover Wirkung und die <div> ein Ereignis hat, das es verschwinden lässt, wenn darauf geklickt wird, dann bekommt mein Link “darunter” den Hover-Effekt angewendet, nachdem das Element aus dem DOM entfernt wurde.

Unten finden Sie ein animiertes GIF dessen, wovon ich spreche:

iOS durchklicken

Ich habe der Schaltfläche einen durchsichtigen Hintergrund gegeben, damit Sie den Link dahinter sehen können. Wenn ich an einer Stelle auf die Schaltfläche tippe, wo der Link ist ist nicht befindet, der Link (dh Some link) bleibt blau und wechselt nicht in den roten Schwebezustand.

Wenn ich jedoch auf die tippe div an einer Stelle, die zufällig ist direkt vorbei der Link, nach dem div aus dem DOM entfernt wird, erhält der Link seinen Hover-Status.

Wenn Sie nach jedem dieser Links auf den Link klicken, wird dieser korrekt ausgelöst on.click Ereignis (ein Warnfenster).

ich unterlassen Sie siehe dieses Problem auf Android in Chrome (siehe Beispiel unten):

Android-Click-Through funktioniert

Unten finden Sie auch das HTML/CSS/JS-Beispiel, das ich verwendet habe; Die Einrichtung ist ziemlich einfach.

Ich möchte, dass sich iOS genauso verhält wie Android Chrome: Das heißt, auf ein Element klicken, das sofort aus dem DOM entfernt wird sollte nicht auslösen a :hover Zustand für ein unmittelbar dahinter liegendes Element.

var button = document.querySelector(".button");
button.addEventListener("click", function() {
  button.parentNode.removeChild(button);
});

var link = document.querySelector('a');
link.addEventListener("click", function() {
  window.alert('clicked!');
});
a:link    { color: blue }
a:visited { color: blue }
a:hover   { color: red }
a:active  { color: green }

.button {
    background: rgba(100, 0, 0, .4);
    position: absolute;
  
    top: 2px;
    left: 2px;
    z-index: 1;

    width: 100px;
    height: 100px;
    line-height: 100px;

    text-align: center;
    border-radius: 5px;
}

.button:hover {
    background: rgba(0, 100, 0, .4);
    cursor: pointer;
}
<a href="#">Some link</a>
<div class="button">Click me!</div>

Benutzer-Avatar
Mailand Jaric

Wenn Sie die Möglichkeit haben, den Hover zu deaktivieren, können Sie dies mit etwas Hack tun.

Fügen Sie zuerst diese Zeile im Ereignishandler “DOMContentLoaded” hinzu.

var canHover = !(matchMedia('(hover: none)').matches);
if (canHover) {
  document.body.classList.add('can-hover');
}

Es fügt die .can-hover-Klasse zum Hauptteil Ihres HTML-Dokuments hinzu.

Bearbeiten Sie dann einfach eine: Hover-Regel, um sie stattdessen anzupassen

deine CSS-Regel:

a:hover {
  color: red;
}

sollte sein:

.can-hover a:hover {
  color: red;
}

Dies sollte verhindern, dass Geräte mit Touchscreen den Hover-Stil auf einen Anker anwenden.

  • Immer noch nicht das Schönste, aber ich mag das besser, da es die Feature-Erkennung anstelle des User-Agent-Sniffing verwendet. Gut genug für mich.

    – Romelem

    16. Januar 2018 um 21:00 Uhr

  • Vielleicht könnten Sie modernizr verwenden, um das Schreiben von Code zu vermeiden, wie ich ihn in der Antwort verwendet habe, damit Ihr App-Code sauberer ist, ohne Hacks. Wie auch immer, ich bin mir nicht sicher, ob Sie Ihr Beispiel ohne Javascript beheben können, da es sich um ein browserübergreifendes Inkonsistenzproblem in der CSS- und HTML-Engine handelt. Ich bin ein bisschen der Meinung, dass es keinen wirklichen Grund gibt, viel Mühe darauf zu verwenden, dass die Seite in allen Browsern gleich aussieht, es sei denn, der Unterschied ist ein Showstopper. Schließlich verwenden die meisten Verbraucher nur einen Browser und verschwenden keine Zeit damit, zu vergleichen, wie Ihre Seite in jedem Browser aussieht.

    – Mailand Jaric

    17. Januar 2018 um 10:09 Uhr

Haben Sie versucht, eine Medienabfrage zu verwenden, um die :hover-Fähigkeit zu testen?

Sehen https://drafts.csswg.org/mediaqueries/#hover

… es ist deutlich zu sehen, dass dies das beabsichtigte Verhalten unter iOS ist, selbst wenn Sie über eine Liste von Hover-fähigen Elementen wischen.

Wenn Sie nur den Schwebeeffekt vermeiden möchten, würde ich Folgendes tun. Ich würde das Gerät mit einer JS-Funktion erhalten, eine Klasse auf die anwenden body Markieren und entfernen Sie nach Bedarf Hover-Effekte.

Javascript:

function isAppleDevice() {
  return (
    (navigator.userAgent.toLowerCase().indexOf("ipad") > -1) ||
    (navigator.userAgent.toLowerCase().indexOf("iphone") > -1) ||
    (navigator.userAgent.toLowerCase().indexOf("ipod") > -1)
   );
}
if (isAppleDevice() {
  $('body').addClass('is_apple')
}

CSS:

.is_apple a:hover {
  // same styling as not hovering
}

  • Ich mag Ihre Antwort, weil ich denke, das Ziel ist es, einen Hover-Effekt zu erzielen, wenn eine Maus vorhanden ist, und die Suche nach “ipad”, “iphone” oder “ipod” deckt diese Entscheidung ab.

    – Joe Hansen

    11. Januar 2018 um 14:52 Uhr

  • @JosephHansen Ich liebe deinen Geist, dass du, obwohl du deine eigene Antwort hast, die Antwort des anderen erkennst. Ich wünschte, jeder hier wäre wie du! Hut ab!

    – Scooterlord

    11. Januar 2018 um 15:14 Uhr

Benutzer-Avatar
JRI

Dies scheint ein beabsichtigtes Verhalten in Safari zu sein. Äpfel Dokumentation sagt, dass Einzelfingertipps als Mausereignisse behandelt werden, und zeigt, welche Ereignisse während eines Tippens ausgelöst werden. Da ist ein mouseover am Anfang des Wasserhahns, aber a mouseout wird nur ausgelöst, wenn Sie auf etwas anderes klicken. Dies bedeutet, dass Safari davon ausgeht, dass der Zeiger bis zum nächsten Tippen an derselben Stelle bleibt, was bedeuten würde, dass sich das untere Element im Schwebezustand befindet.

Ich habe Ihren Code in Chrome unter Android und Chrome und Firefox unter Windows ausprobiert (ich habe kein Apple-Gerät). In allen drei Fällen, wenn ich auf die klicke <div> Wenn Sie eine Maus (über den Link) verwenden, wird der Hover-Stil anschließend auf den Link angewendet, es sei denn, ich bewege den Cursor vom Link weg, bevor ich die Maus loslasse. Wenn ich auf die tippe <div> Mit meinem Finger auf dem Touchscreen bekommt der Link nicht den Hover-Stil.

Firefox und Chrome scheinen für Berührung und Maus konsistent zu sein, aber Safari scheint (von Natur aus) den Touchscreen wie eine Maus zu behandeln: Er verhält sich bei einem Berührungsdruck genauso wie Chrome und Firefox bei einem Mausklick.

Ich glaube nicht, dass dies ein Fehler ist, den Sie beheben oder umgehen müssen. Sofern Sie nicht wissen, dass alle Ihre Benutzer eine bestimmte Hardware-/Browser-Kombination verwenden, müssen Sie wahrscheinlich für den Fall einplanen, dass sie eine Maus, einen Touchscreen oder vielleicht beides gleichzeitig verwenden könnten. und entwerfen Sie eine Benutzeroberfläche, die für alle diese Fälle funktioniert. Mein Windows-Laptop und mein Android-Tablet haben sowohl Mauspads als auch Touchscreens, und ich verwende manchmal eine USB-OTG-Maus mit meinem Android-Telefon.

Könnte man sich auch anschauen API für Zeigerereignissedas in Chrome, IE und Edge funktioniert (nicht zu verwechseln mit der Zeigerereignisse Von @erier erwähnte CSS-Eigenschaft). Da die API eher mit Ereignissen als mit CSS arbeitet, hilft dies nicht direkt dabei, Ihr Styling richtig zu machen, zeigt aber die Anstrengungen, die unternommen werden, um Browser dazu zu bringen, konsistent auf verschiedene Arten von Eingabegeräten zu reagieren.

Probieren Sie die neue Medienabfragemethode aus, um zu testen, ob der primäre Eingabemechanismus des Benutzers über Elemente schweben kann.

@media (hover) {
  // Your hover effects
  a:hover {
    color: red;
  }
}

Dokumente: hover – CSS: Cascading Stylesheets | MDN

Dies scheint eine inhärente Designentscheidung in iOS zu sein (oder vielleicht ist der Chrome-Weg die Designentscheidung, die von ihnen getroffen wird; kann es nicht sagen). Es scheint, dass iOS so konzipiert ist, dass es “mausähnlich” ist. Es wirft sogar „Mouseovers“ auf Webseiten, sogar auf ihren Nur-Touch-Geräten. Ich habe versucht, einen Weg zu finden, um festzustellen, ob der Benutzer eine Maus hat, damit Sie Hover-Effekte deaktivieren können, falls vorhanden, aber ich kann nichts finden, was richtig funktioniert.

Ich denke, Windows macht das auch mit Touch. Das Berühren eines Punktes bewegt den Mauszeiger effektiv dorthin und klickt, wobei der Mauszeiger stehen bleibt.

Möglicherweise müssen Sie nur Ihr Design ändern, wenn dies ein Deal-Breaker ist.

Benutzer-Avatar
Marmelade

Ich hatte ein ähnliches Problem, das ich gelöst habe, indem ich kurz vor dem Entfernen des Elements für den Bruchteil einer Sekunde Zeigerereignisse none hinzufügte und es dann wieder zurücksetzte, nachdem es weg war.

document.addEventListener("DOMContentLoaded", function ready() {
  var button = document.querySelector(".button");
  button.addEventListener("click", function() {
    document.querySelector('a').classList.add("no-click");
    button.parentNode.removeChild(button);
    setTimeout(function() {
        document.querySelector('a').classList.remove("no-click");
    },1);
  });
  
  document.querySelector('a').addEventListener("click", function() {
    window.alert('clicked!');
  });
});
a:link    { color: blue }
a:visited { color: blue }
a:hover   { color: red }
a:active  { color: green }

.button {
    background: rgba(100, 0, 0, .4);
    position: absolute;
  
    top: 2px;
    left: 2px;
    z-index: 1;

    width: 100px;
    height: 100px;
    line-height: 100px;

    text-align: center;
    border-radius: 5px;
}

.button:hover {
    background: rgba(0, 100, 0, .4);
    cursor: pointer;
}
.no-click {
    pointer-events: none;
}
<a href="#">Some link</a>
<div class="button">Click me!</div>

1049280cookie-checkEin Klick in iOS Safari löst einen „Hover-Status“ auf dem Element aus, auf das Sie getippt haben

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy