it-swarm.com.de

Entfernen/Ignorieren: Hover-CSS-Stil auf Touch-Geräten

Ich möchte alle :hover CSS-Deklarationen ignorieren, wenn ein Benutzer unsere Website über ein Touchgerät besucht. Das :hover-CSS macht keinen Sinn, und es kann sogar störend sein, wenn ein Tablet es beim Klicken/Antippen auslöst, da es sonst hängen bleibt, bis das Element den Fokus verliert. Um ehrlich zu sein, weiß ich nicht, warum Touch-Geräte an erster Stelle :hover auslösen müssen - aber das ist Realität, also ist dieses Problem auch Realität.

a:hover {
   color:blue;
   border-color:green;
   // etc. > ignore all at once for touch devices
}

Also (wie) kann ich alle CSS :hover-Deklarationen auf einmal entfernen (ohne sie zu kennen), nachdem sie deklariert wurden?

76

Es gibt mehrere Lösungen für dieses Problem.

Quick'n'Dirty - Remove: Hover-Stile mit JS

Sie können alle CSS-Regeln, die :hover enthalten, mit Javascript entfernen. Dies hat den Vorteil, dass Sie kein CSS berühren müssen und auch mit älteren Browsern kompatibel sind.

function hasTouch() {
    return 'ontouchstart' in document.documentElement
           || navigator.maxTouchPoints > 0
           || navigator.msMaxTouchPoints > 0;
}

if (hasTouch()) { // remove all :hover stylesheets
    try { // prevent exception on browsers not supporting DOM styleSheets properly
        for (var si in document.styleSheets) {
            var styleSheet = document.styleSheets[si];
            if (!styleSheet.rules) continue;

            for (var ri = styleSheet.rules.length - 1; ri >= 0; ri--) {
                if (!styleSheet.rules[ri].selectorText) continue;

                if (styleSheet.rules[ri].selectorText.match(':hover')) {
                    styleSheet.deleteRule(ri);
                }
            }
        }
    } catch (ex) {}
}

Einschränkungen: Stylesheets müssen auf der gleichen Domäne (dh keine CDNs) gehostet werden. Deaktiviert Hover auf gemischten Maus- und Touch-Geräten wie Surface, was die UX verletzt.

Nur für CSS - Verwenden Sie Medienabfragen

Platzieren Sie alle Ihre: hover-Regeln in einem @media-Block:

@media (hover: hover) {
    a:hover { color: blue; }
}

oder überschreiben Sie alternativ alle Hover-Regeln (kompatibel mit älteren Browsern):

a:hover { color: blue; }

@media (hover: none) {
    a:hover { color: inherit; }
}

Einschränkungen: Funktioniert nur unter iOS 9.0, Chrome für Android oder Android 5.0 und höher, wenn WebView verwendet wird. hover: hover unterbricht Hover-Effekte in älteren Browsern, hover: none muss alle zuvor definierten CSS-Regeln überschreiben. Beide sind nicht kompatibel mit gemischten Maus- und Touchgeräten.

Am robustesten - verwenden Sie spezielle CSS-Klassen und erkennen Sie die Berührung über JS

Diese Methode muss alle Hover-Regeln mit body.hasHover voranstellen. (oder ein Klassenname Ihrer Wahl)

body.hasHover a:hover { color: blue; }

Die hasHover-Klasse kann mit hasTouch() aus dem ersten Beispiel hinzugefügt werden:

if (!hasTouch()) {
    document.body.className += ' hasHover';
}

Dies hat jedoch bei gemischten Berührungsgeräten das gleiche Problem wie bei den vorherigen Beispielen, was uns zur endgültigen Lösung bringt. Aktivieren Sie Hover-Effekte, wenn ein Mauszeiger bewegt wird, und deaktivieren Sie Hover-Effekte, wenn eine Berührung erkannt wird.

function watchForHover() {
    var hasHoverClass = false;
    var container = document.body;
    var lastTouchTime = 0;

    function enableHover() {
        // filter emulated events coming from touch events
        if (new Date() - lastTouchTime < 500) return;
        if (hasHoverClass) return;

        container.className += ' hasHover';
        hasHoverClass = true;
    }

    function disableHover() {
        if (!hasHoverClass) return;

        container.className = container.className.replace(' hasHover', '');
        hasHoverClass = false;
    }

    function updateLastTouchTime() {
        lastTouchTime = new Date();
    }

    document.addEventListener('touchstart', updateLastTouchTime, true);
    document.addEventListener('touchstart', disableHover, true);
    document.addEventListener('mousemove', enableHover, true);

    enableHover();
}

watchForHover();

Dies sollte grundsätzlich in jedem Browser funktionieren und bei Bedarf Hover-Stile aktivieren/deaktivieren. Probieren Sie es hier aus: https://jsfiddle.net/dkz17jc5/19/

92
blade

Zeigeranpassung zur Rettung!

Da dies seit einiger Zeit nicht mehr angerührt wurde, können Sie Folgendes verwenden:

a:link {
   color: red;
}

a:hover {
   color:blue;
}

@media (hover: none) {
   a:link {
      color: red;
   }
}

Sehen Sie sich diese Demo sowohl in Ihrem Desktop-Browser als auch in Ihrem Telefon-Browser an . Unterstützt von modernen Touchgeräten .

Note: Denken Sie daran, dass die primäre Eingabe (Fähigkeit) eines Surface-PCs eine Maus ist, was zu einem blauen Link wird, auch wenn es sich um einen separaten Tablet-Bildschirm handelt. Browser werden (sollte) immer die genauesten Eingabefunktionen verwenden.

30

Ich beschäftige mich derzeit mit einem ähnlichen Problem.

Es gibt zwei main -Optionen, die mir sofort einfallen: (1) Überprüfung der Benutzerzeichenfolge oder (2) Pflege separater Handy-Seiten unter Verwendung einer anderen URL und Auswahl der für die Benutzer besseren.

  1. Wenn Sie in der Lage sind, eine Internet-Klebebandsprache wie PHP oder Ruby) zu verwenden, können Sie die Benutzerzeichenfolge überprüfen des Geräts, das eine Seite anfordert, und dienen einfach den gleichen Inhalt, aber mit einem <link rel="mobile.css" /> anstelle des normalen Stils.

Benutzer-Strings haben identifizierende Informationen über Browser, Renderer, Betriebssystem usw. Es liegt an Ihnen, zu entscheiden, welche Geräte "touch" oder "non-touch" sind. Möglicherweise finden Sie diese Informationen irgendwo und ordnen sie Ihrem System zu.

A. Wenn Sie alte Browser ignorieren dürfen , müssen Sie nur eine einzige Regel zur normalen, nicht mobilen CSS hinzufügen, nämlich:  EDIT : Erk. Nach einigen Experimenten stellte ich fest, dass die folgende Regel nicht nur das Verfolgen von Links in Webkit-Browsern verhindert, sondern auch das Deaktivieren von ästhetischen Effekten - siehe http://jsfiddle.net/3nkcdeao/
Daher müssen Sie etwas gezielter vorgehen, um die Regeln für den mobilen Fall zu ändern, als hier gezeigt, aber dies kann ein hilfreicher Ausgangspunkt sein:

* { 
    pointer-events: none !important; /* only use !important if you have to */
}

Als Randbemerkung bewirkt das Deaktivieren von Zeigerereignissen für ein übergeordnetes Element und das anschließende explizite Aktivieren dieser Ereignisse für ein untergeordnetes Element, dass Hover-Effekte für das übergeordnete Element wieder aktiv werden, wenn ein untergeordnetes Element :hover Eingibt.
Siehe http://jsfiddle.net/38Lookhp/5/

B. Wenn Sie ältere Web-Renderer unterstützen, müssen Sie ein wenig mehr tun, um Regeln zu entfernen, die spezielle Stile während :hover Festlegen. Um Zeit zu sparen, möchten Sie möglicherweise nur einen automatisierten Kopierbefehl sed erstellen, den Sie auf Ihren Standard-Stylesheets ausführen, um die Mobilversionen zu erstellen. Auf diese Weise können Sie einfach den Standardcode schreiben/aktualisieren und alle Stilregeln entfernen, die :hover Für die mobile Version Ihrer Seiten verwenden.

  1. (I) Alternativ können Sie Ihre Benutzer auch darauf hinweisen, dass Sie zusätzlich zu Ihrer website.com eine m.website.com für Mobilgeräte haben. Obwohl Subdomaining die häufigste Methode ist, können Sie auch eine andere vorhersehbare Änderung einer bestimmten URL vornehmen, um mobilen Benutzern den Zugriff auf die geänderten Seiten zu ermöglichen. In diesem Stadium möchten Sie sichergehen, dass sie die URL nicht jedes Mal ändern müssen, wenn sie zu einem anderen Teil der Site navigieren.

Auch hier können Sie möglicherweise nur ein oder zwei zusätzliche Regeln zu den Stylesheets hinzufügen oder mit sed oder einem ähnlichen Dienstprogramm etwas Komplizierteres tun. Es ist wahrscheinlich am einfachsten, es anzuwenden: Nicht auf Ihre Styling-Regeln wie div:not(.disruptive):hover {..., bei denen Sie class="disruptive" Zu Elementen hinzufügen, die für mobile Benutzer ärgerliche Dinge mit js oder der Serversprache tun, anstatt das zu mischen CSS.

  1. (II) Sie können die ersten beiden kombinieren und (wenn Sie den Verdacht haben, dass ein Benutzer zur falschen Version einer Seite gewandert ist) vorschlagen, dass er in die mobile Anzeige wechselt bzw. diese wieder verlässt, oder einfach irgendwo einen Link haben Ermöglicht Benutzern das Hin- und Herfloppen. Wie bereits erwähnt, können @media-Abfragen auch dazu verwendet werden, festzustellen, was für Besuche verwendet werden.

  2. (III) Wenn Sie für eine jQuery-Lösung bereit sind, sobald Sie wissen, welche Geräte "touch" sind und welche nicht, werden CSS-Hover auf Touchscreen-Geräten möglicherweise nicht ignoriert hilfreich.

7
SeldomNeedy

Ich bin auf das gleiche Problem gestoßen (in meinem Fall mit mobilen Browsern von Samsung) und bin daher auf diese Frage gestoßen. 

Dank der Antwort von Calsal habe ich etwas gefunden, von dem ich glaube, dass es praktisch alle Desktop-Browser ausschließt, weil es von den mobilen Browsern, die ich ausprobiert habe, erkannt wird (siehe Screenshot aus einer kompilierten Tabelle: CSS-Zeiger-Feature-Erkennungstabelle ) .

MDN-Webdokumente Geben Sie das an 

Die CSS @media-Zeigerfunktion kann verwendet werden, um Stile basierend auf .__ anzuwenden. ob der primäre Eingabemechanismus des Benutzers ein Zeigegerät ist, und Wenn ja, wie genau ist das?

.

Was ich entdeckt habe, ist, dass pointer: grob etwas ist, das allen Desktop-Browsern in der angefügten Tabelle unbekannt ist, aber allen mobilen Browsern in derselben Tabelle bekannt ist. Dies scheint die effektivste Wahl zu sein, da alle anderen Zeigerschlüsselwortwerte inkonsistente Ergebnisse liefern.

Daher können Sie eine Medienabfrage wie Calsal erstellen, jedoch etwas modifiziert. Es verwendet eine umgekehrte Logik, um alle Touch-Geräte auszuschließen.

Sass Mixin:

@mixin hover-supported {    
    /* 
     * https://developer.mozilla.org/en-US/docs/Web/CSS/@media/pointer 
     * coarse: The primary input mechanism includes a pointing device of limited accuracy.
     */
    @media not all and (pointer: coarse) {
        &:hover {
            @content;
        }
    }
}

a {
    color:green;
    border-color:blue;

    @include hover-supported() {
        color:blue;
        border-color:green;
    }
}

Kompiliertes CSS:

a {
  color: green;
  border-color: blue;
}
@media not all and (pointer: coarse) {
  a:hover {
    color: blue;
    border-color: green;
  }
}

Es wird auch in diesem Gist beschrieben, das ich nach Erforschung des Problems erstellt habe. -. Codepen für empirische Forschung.

UPDATE: Zum Zeitpunkt des Schreibens dieses Updates, 2018-08-23, und von @DmitriPavlutin darauf hingewiesen, scheint diese Technik nicht mehr mit Firefox-Desktop zu funktionieren.

5
ProgrammerPer

versuche dies:

@media (hover:<s>on-demand</s>) {
    button:hover {
        background-color: #color-when-NOT-touch-device;
    }
}

UPDATE: Leider hat W3C diese Eigenschaft aus den Spezifikationen entfernt ( https://github.com/w3c/csswg-drafts/commit/2078b46218f7462735bb0b5b7b9103c9a3e84fb4c4b1 ).

5
Marouen Mhiri

Sie können Modernizr JS verwenden (siehe auch StackOverflow-Antwort ) oder eine benutzerdefinierte JS-Funktion erstellen:

function is_touch_device() {
 return 'ontouchstart' in window        // works on most browsers 
  || navigator.maxTouchPoints;       // works on IE10/11 and Surface
};

if ( is_touch_device() ) {
  $('html').addClass('touch');
} else {
  $('html').addClass('no-touch');
} 

um die Unterstützung für das touch -Ereignis im Browser zu erkennen, und weisen Sie dann eine reguläre CSS -Eigenschaft zu, die das Element mit der html.no-touch-Klasse durchläuft, wie folgt:

html.touch a {
    width: 480px;
}

/* FOR THE DESKTOP, SET THE HOVER STATE */
html.no-touch a:hover {
   width: auto;
   color:blue;
   border-color:green;
}
4
Giacomo Paita

Laut Jasons Antwort können wir nur Geräte ansprechen, die Hover nicht mit reinen CSS-Medienabfragen unterstützen. Wir können auch nur Geräte ansprechen, die Hover unterstützen, wie moogal's answer in einer ähnlichen Frage, mit @media not all and (hover: none). Es sieht komisch aus, aber es funktioniert.

Ich habe daraus ein Sass-Mixin für die einfachere Verwendung gemacht:

@mixin hover-supported {
    @media not all and (hover: none) {
        &:hover {
            @content;
        }
    }
}

Folgendes würde die Hintergrundfarbe von .container für Geräte, die dies unterstützen, von rot zu blau ändern und für Touch-Geräte rot bleiben:

.container {
    background-color: red;

    @include hover-supported() {
        background-color: blue;
    }
}
1
Calsal

Dies ist auch eine mögliche Problemumgehung, aber Sie müssen Ihre CSS durchgehen und vor den Hover-Styles eine .no-touch-Klasse hinzufügen.

Javascript:

if (!("ontouchstart" in document.documentElement)) {
document.documentElement.className += " no-touch";
}

CSS-Beispiel:

<style>
p span {
    display: none;
}

.no-touch p:hover span {
    display: inline;
}
</style>
<p><a href="/">Tap me</a><span>You tapped!</span></p>

Quelle

P.s. Wir sollten jedoch bedenken, dass immer mehr Touch-Geräte auf den Markt kommen, die gleichzeitig die Mauseingabe unterstützen. 

1
mr.mii

Dies ist möglicherweise noch keine perfekte Lösung (und zwar mit jQuery), aber es ist vielleicht eine Richtung/Konzept, an dem gearbeitet werden muss: Was ist, wenn man es anders herum macht? Dies bedeutet, dass standardmäßig die: hover-css-Status deaktiviert und aktiviert werden, wenn ein Mousemove-Ereignis an einer beliebigen Stelle im Dokument erkannt wird. Das funktioniert natürlich nicht, wenn jemand js deaktiviert hat. Was kann sich noch dagegen aussprechen?

Vielleicht so:

CSS:

/* will only work if html has class "mousedetected" */
html.mousedetected a:hover {
   color:blue;
   border-color:green;
}

jQuery:

/* adds "mousedetected" class to html element if mouse moves (which should never happen on touch-only devices shouldn’t it?) */
$("body").mousemove( function() {
    $("html").addClass("mousedetected");
});
1

Der schmutzige Weg ... Nicht elegant, aber der einfachste Weg, der Sie retten kann.

Entfernen Sie alles, was den Schwebeflug kennzeichnet.

.your-class:hover:before {
  color: blue;
  background: linear-gradient(to bottom, rgba(231,56,39,0) 0%, #aaaaaa 100%);
}

@media all and (min-width:320px) and (max-width: 960px) {
    .your-class:hover:before {
    color: black;
    background: transparent;
  }
}
0
Fellipe Sanches

Es war hilfreich für mich: link

function hoverTouchUnstick() {
    // Check if the device supports touch events
    if('ontouchstart' in document.documentElement) {
        // Loop through each stylesheet
        for(var sheetI = document.styleSheets.length - 1; sheetI >= 0; sheetI--) {
            var sheet = document.styleSheets[sheetI];
            // Verify if cssRules exists in sheet
            if(sheet.cssRules) {
                // Loop through each rule in sheet
                for(var ruleI = sheet.cssRules.length - 1; ruleI >= 0; ruleI--) {
                    var rule = sheet.cssRules[ruleI];
                    // Verify rule has selector text
                    if(rule.selectorText) {
                        // Replace hover psuedo-class with active psuedo-class
                        rule.selectorText = rule.selectorText.replace(":hover", ":active");
                    }
                }
            }
        }
    }
}
0
mineroot

Versuchen Sie dies (in diesem Beispiel verwende ich Hintergrund und Hintergrundfarbe):

var ClickEventType = ((document.ontouchstart !== null) ? 'click' : 'touchstart');

if (ClickEventType == 'touchstart') {
            $('a').each(function() { // save original..
                var back_color = $(this).css('background-color');
                var background = $(this).css('background');
                $(this).attr('data-back_color', back_color);
                $(this).attr('data-background', background);
            });

            $('a').on('touchend', function(e) { // overwrite with original style..
                var background = $(this).attr('data-background');
                var back_color = $(this).attr('data-back_color');
                if (back_color != undefined) {
                    $(this).css({'background-color': back_color});
                }
                if (background != undefined) {
                    $(this).css({'background': background});
                }
            }).on('touchstart', function(e) { // clear added stlye="" elements..
                $(this).css({'background': '', 'background-color': ''});
            });
}

cSS:

a {
    -webkit-touch-callout: none;
    -webkit-tap-highlight-color: transparent;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}
0
HU TanKy

Versuchen Sie diese einfache 2019-Jquery-Lösung, obwohl es schon eine Weile her ist;

  1. fügen Sie dieses Plugin dem Kopf hinzu: 

    src = "https://code.jquery.com/ui/1.12.0/jquery-ui.min.js"

  2. füge dies zu js hinzu:

    $ ("*"). on ("touchend") Funktion (e) {$ (this) .focus ();}); // gilt für alle Elemente

  3. einige vorgeschlagene Variationen dazu sind:

    $ (": input,: checkbox,"). on ("touchend", function (e) {(this) .focus);}); // Elemente angeben

    $ ("*"). on ("click, touchend"), Funktion (e) {$ (this) .focus ();}); // Click-Event einschließen

    css: body {Cursor: Zeiger; } // Berühren Sie eine beliebige Stelle, um den Fokus zu beenden

Anmerkungen 

  • platzieren Sie das Plugin vor bootstrap.js, um die Tooltips nicht zu beeinträchtigen
  • nur auf iPhone XR iOS 12.1.12 und iPad 3 iOS 9.3.5 mit Safari oder Chrome getestet.

Verweise:

https://code.jquery.com/ui/

https://api.jquery.com/category/selectors/jquery-selector-extensions/

0
darren