Disabilita gli effetti al passaggio del mouse sui browser mobili


113

Sto scrivendo un sito Web che deve essere utilizzato sia da desktop che da tablet. Quando viene visitato da un desktop, voglio che le aree cliccabili dello schermo si illuminino con :hovereffetti (diverso colore di sfondo, ecc.) Con un tablet, non c'è mouse, quindi non voglio effetti al passaggio del mouse.

Il problema è che quando tocco qualcosa sul tablet, il browser ha evidentemente una sorta di "cursore del mouse invisibile" che si sposta nella posizione che ho toccato e poi lo lascia lì, quindi la cosa che ho appena toccato si accende con un effetto hover finché non tocco qualcos'altro.

Come posso ottenere gli effetti al passaggio del mouse quando utilizzo il mouse, ma sopprimerli quando utilizzo il touchscreen?

Nel caso qualcuno stesse pensando di suggerirlo, non voglio usare lo sniffing dello user-agent. Lo stesso dispositivo potrebbe avere sia un touchscreen che un mouse (forse non così comune oggi, ma molto di più in futuro). Non mi interessa il dispositivo, mi interessa come viene attualmente utilizzato: mouse o touchscreen.

Ho già provato agganciando i touchstart, touchmove, e touchendgli eventi e chiamando preventDefault()su ognuna di esse, che fa sopprimere il "cursore del mouse invisibile" per qualche tempo; ma se tocco rapidamente avanti e indietro tra due elementi diversi, dopo pochi tocchi inizierà a spostare il "cursore del mouse" e ad illuminare comunque gli effetti hover - è come se il mio preventDefaultnon fosse sempre onorato. Non ti annoierò con i dettagli a meno che non sia necessario - non sono nemmeno sicuro che sia l'approccio giusto da adottare; se qualcuno ha una soluzione più semplice, sono tutt'orecchi.


Modifica: può essere riprodotto con CSS standard di bog :hover, ma ecco una rapida riproduzione per riferimento.

<style>
  .box { border: 1px solid black; width: 150px; height: 150px; }
  .box:hover { background: blue; }
</style>
<div class="box"></div>
<div class="box"></div>

Se passi il mouse su una delle caselle, verrà visualizzato uno sfondo blu, che voglio. Ma se tocchi una delle caselle, verrà visualizzato anche uno sfondo blu, che è la cosa che sto cercando di evitare.

Ho anche pubblicato un esempio qui che fa quanto sopra e aggancia anche gli eventi del mouse di jQuery. Puoi usarlo per vedere che anche gli eventi di tocco verranno attivati mouseenter,mousemove e mouseleave.


7
@ Blender, hai letto la domanda? Ho già spiegato perché lo sniffing dello user-agent è una cattiva scelta.
Joe White

Hey Joe, hai trovato qualche soluzione per questo?
Ismatjon

Stavo cercando questo tipo di domanda, felice di averlo trovato!
agpt

Vedi anche questa domanda, che riguarda la disabilitazione del passaggio del mouse su qualsiasi dispositivo abilitato al tocco, non solo mobile: stackoverflow.com/questions/23885255/…
blade

Risposte:


83

Dalla tua domanda deduco che il tuo effetto hover cambia il contenuto della tua pagina. In tal caso, il mio consiglio è di:

  • Aggiungi effetti al passaggio del mouse su touchstarte mouseenter.
  • Rimuovere hover effetti su mouseleave, touchmovee click.

In alternativa, puoi modificare la tua pagina in modo che non ci siano cambiamenti di contenuto.

sfondo

Per simulare un mouse, i browser come Webkit mobile attivano i seguenti eventi se un utente tocca e rilascia un dito sul touch screen (come iPad) (fonte: Touch And Mouse su html5rocks.com):

  1. touchstart
  2. touchmove
  3. touchend
  4. Ritardo di 300 ms, in cui il browser si assicura che si tratti di un singolo tocco, non di un doppio tocco
  5. mouseover
  6. mouseenter
    • Nota : se una mouseover, mouseentero mousemoveevento cambia il contenuto della pagina, i seguenti eventi vengono mai sparato.
  7. mousemove
  8. mousedown
  9. mouseup
  10. click

Non sembra possibile dire semplicemente al browser web di saltare gli eventi del mouse.

Quel che è peggio, se un evento al passaggio del mouse cambia il contenuto della pagina, l'evento clic non viene mai attivato, come spiegato nella Guida ai contenuti web di Safari - Gestione degli eventi , in particolare nella figura 6.4 in Eventi con un dito . Che cos'è esattamente un "cambio di contenuto" dipenderà dal browser e dalla versione. Ho scoperto che per iOS 7.0, una modifica del colore di sfondo non è (o non è più?) Una modifica del contenuto.

Soluzione spiegata

Ricapitolando:

  • Aggiungi effetti al passaggio del mouse su touchstartemouseenter.
  • Rimuovere hover effetti su mouseleave, touchmovee click.

Notare che non è prevista alcuna azione touchend !

Questo chiaramente funziona per gli eventi del mouse: mouseentere mouseleave(versioni leggermente migliorate di mouseovere mouseout) vengono attivate e aggiungono e rimuovono il passaggio del mouse.

Se l'utente utilizza effettivamente clickun collegamento, viene rimosso anche l'effetto hover. Ciò garantisce che venga rimosso se l'utente preme il pulsante Indietro nel browser web.

Funziona anche per eventi touch: al touchstart viene aggiunto l'effetto hover. È '' 'non' '' rimosso al tocco. Viene aggiunto di nuovo mouseentere poiché ciò non causa modifiche al contenuto (era già stato aggiunto), clickviene anche attivato l' evento e il collegamento viene seguito senza che l'utente debba fare nuovamente clic!

Il ritardo di 300 ms che un browser ha tra un touchstartevento eclick viene effettivamente utilizzato correttamente perché l'effetto hover verrà mostrato durante questo breve periodo.

Se l'utente decide di annullare il clic, un movimento del dito lo farà normalmente. Normalmente, questo è un problema poiché non mouseleaveviene generato alcun evento e l'effetto hover rimane in vigore. Per fortuna, questo può essere facilmente risolto rimuovendo l'effetto hover su touchmove.

Questo è tutto!

Si noti che è possibile rimuovere il ritardo di 300 ms, ad esempio utilizzando la libreria FastClick , ma questo non rientra nell'ambito di questa domanda.

Soluzioni alternative

Ho riscontrato i seguenti problemi con le seguenti alternative:

  • rilevamento del browser: estremamente soggetto a errori. Si presume che un dispositivo abbia il mouse o il tocco, mentre una combinazione di entrambi diventerà sempre più comune quando i display tattili prolifera.
  • Rilevamento dei supporti CSS: l'unica soluzione solo CSS di cui sono a conoscenza. Ancora soggetto a errori e presume ancora che un dispositivo abbia il mouse o il tocco, mentre entrambi sono possibili.
  • Emula l'evento clic in touchend: questo seguirà in modo errato il collegamento, anche se l'utente desidera solo scorrere o eseguire lo zoom, senza l'intenzione di fare effettivamente clic sul collegamento.
  • Usa una variabile per sopprimere gli eventi del mouse: imposta una variabile touchendche viene utilizzata come condizione if negli eventi del mouse successivi per evitare cambiamenti di stato in quel momento. La variabile viene reimpostata nell'evento clic. Vedi la risposta di Walter Roman in questa pagina. Questa è una soluzione decente se davvero non vuoi un effetto hover sulle interfacce touch. Sfortunatamente, questo non funziona se un touchendviene attivato per un altro motivo e nessun evento di clic viene attivato (ad es. L'utente ha fatto scorrere o zumato), e successivamente sta tentando di seguire il collegamento con un mouse (ad esempio su un dispositivo con interfaccia sia mouse che touch ).

Ulteriori letture


1
Bella risposta. Ho usato il tuo violino per iniziare a creare la mia soluzione. Tuttavia, a volte è necessario il touchend. (quando un movimento tattile non viene eseguito, ovvero quando l'utente si allontana dal documento stesso ...)
Agamemnus

Grande risposta ma nella maggior parte dei casi suggerirei usando touchend al posto di touchstartnella maggior parte dei casi, per evitare azioni innescando immediatamente quando l'utente sta tentando di strisciare-scorrere verso l'alto o verso il basso di una pagina. Accadrà ancora ma è meno probabile che distragga o confonda (supponendo che sia qualcosa di innocuo come la visualizzazione di un'etichetta, non qualcosa che l'utente deve sapere che è successo)
user56reinstatemonica8

19

Come posso ottenere gli effetti al passaggio del mouse quando utilizzo il mouse, ma sopprimerli quando utilizzo il touchscreen?

Forse non pensarlo tanto come sopprimere gli effetti al passaggio del mouse per i touchscreen, ma come aggiungere effetti al passaggio del mouse per gli eventi del mouse?

Se vuoi mantenere gli :hovereffetti nel tuo CSS puoi specificare diversi stili per diversi media:

@media screen { /* hover styles here */ } 

@media handheld { /* non-hover styles here */ }

Tranne che sfortunatamente ci sono molti dispositivi mobili che ignorano questo e usano solo le regole dello schermo. Fortunatamente molti browser per dispositivi mobili / tablet più recenti supportano alcune query multimediali più elaborate:

@media screen and (max-width:800px) { /* non-hover styles here */ }

Quindi, anche se la parte "schermo" o "palmare" viene ignorata, la "larghezza massima" farà il trucco per te. Puoi semplicemente presumere che qualsiasi cosa con uno schermo più piccolo di 800 pixel debba essere un tablet o un telefono e non utilizzare effetti al passaggio del mouse. Per i rari utenti che utilizzano un mouse su un dispositivo a bassa risoluzione non vedrebbero gli effetti al passaggio del mouse, ma altrimenti il ​​tuo sito andrebbe bene.

Ulteriori letture sulle media query? Ci sono molti articoli su questo online - eccone uno: http://www.alistapart.com/articles/return-of-the-mobile-stylesheet

Se sposti gli effetti al passaggio del mouse fuori dal tuo CSS e li applichi con JavaScript, potresti associarti in modo specifico agli eventi del mouse e / o ancora potresti fare alcune supposizioni solo in base alle dimensioni dello schermo con il "problema" peggiore che è che alcuni l'utente che utilizza un mouse perde gli effetti al passaggio del mouse.


Mi piacerebbe aggiungere effetti al passaggio del mouse solo per gli eventi del mouse. Ma gli eventi touch emulano gli eventi del mouse. Se aggancio gli eventi di tocco e chiamo preventDefault(), a volte sopprime gli eventi del mouse, ma come ho detto nella mia domanda, non è affidabile.
Joe White

6
Per quanto riguarda le media query, cosa succede quando esce Windows 8 ei PC hanno sia touchscreen che mouse? Se l'utente passa con il mouse, vedrà il cursore del mouse e voglio gli effetti al passaggio del mouse; se toccano con il touchscreen, non voglio gli effetti al passaggio del mouse. Ma non ho trovato un modo affidabile per rilevare la differenza tra tocco e mouse.
Joe White

Ebbene, forse gli sviluppatori di browser saranno più motivati ​​a rendere il rilevamento più coerente una volta che avranno un numero maggiore di utenti su dispositivi con tocco e mouse. Ma per ora? Farei ipotesi in base alle dimensioni dello schermo, ma ci sono altri consigli nelle altre risposte. Mi dispiace, non posso aiutarti ulteriormente.
nnnnnn

9

Ho scritto il seguente JS per un progetto recente, che era un sito desktop / mobile / tablet con effetti al passaggio del mouse che non dovrebbero apparire al tocco.

Il mobileNoHoverState modulo sottostante ha una variabile preventMouseover(inizialmente dichiarata come false), che viene impostato truequando un utente genera l' touchstartevento su un elemento, $target.

preventMouseoverviene quindi reimpostato su falseogni volta mouseoverche viene generato l' evento, il che consente al sito di funzionare come previsto se un utente utilizza sia il touchscreen che il mouse.

Sappiamo che mouseoverviene attivato dopo a touchstartcausa dell'ordine in cui vengono dichiarati init.

var mobileNoHoverState = function() {

    var hoverClass = 'hover',
        $target = $(".foo"), 
        preventMouseover = false;

    function forTouchstart() {
        preventMouseover = true;
    }

    function forMouseover() {
        if (preventMouseover === false) {
            $(this).addClass(hoverClass);
        } else {
            preventMouseover = false;
        }
    }

    function forMouseout() {
        $(this).removeClass(hoverClass);
    }

    function init() {
        $target.on({
            touchstart  : forTouchstart,
            mouseover   : forMouseover,
            mouseout    : forMouseout
        });                
    }

    return {
        init: init
    };
}();

Il modulo viene quindi istanziato più in basso sulla linea:

mobileNoHoverState.init();

"preventMouseover viene quindi reimpostato su true ogni volta che viene attivato l'evento mouseover, il che consente al sito di funzionare come previsto se un utente utilizza sia il touchscreen che il mouse." - Il tuo codice non lo fa. Mi sto perdendo qualcosa?
Redtopia

@Redtopia Grazie per l'avvertimento! Ho aggiornato la risposta con il bit di codice che è stato tralasciato.
Walter Roman

Non è necessario il punto e virgola dopo la dichiarazione della funzione
nacholibre

@nacholibre È stato implementato un corretto utilizzo del punto e virgola
Walter Roman,

6

Volevo davvero una csssoluzione pura a questo io stesso, dal momento che spargere una pesante soluzione javascript intorno a tutte le mie visualizzazioni sembrava un'opzione spiacevole. Infine è stata trovata la query @ media.hover , che può rilevare "se il meccanismo di input principale consente all'utente di passare con il mouse sugli elementi". Ciò evita i dispositivi di tocco in cui "hovering" è più un'azione emulata che una capacità diretta del dispositivo di input.

Quindi, ad esempio, se ho un link:

<a href="/" class="link">Home</a>

Quindi posso tranquillamente modellarlo solo :hoverquando il dispositivo lo supporta facilmente con questo css:

@media (hover: hover) {
  .link:hover { /* hover styles */ }
}

Mentre la maggior parte dei browser moderni supporta le query di funzionalità multimediali di interazione, alcuni browser popolari come IE e Firefox non lo fanno. Nel mio caso funziona bene, poiché intendevo supportare solo Chrome su desktop e Chrome e Safari su dispositivi mobili.


Bella soluzione che sembra funzionare quando emuli dispositivi in ​​Chrome devtools. Ma ancora non funziona per Chrome Android :-(
Sjeiti

Penso che questa sia la soluzione più conveniente e corretta. Spero che venga presto aggiunto agli standard W3C.
GProst

5

La mia soluzione è aggiungere una classe CSS attiva al passaggio del mouse al tag HTML e usarla all'inizio di tutti i selettori CSS con: hover e rimuovi quella classe al primo evento touchstart.

http://codepen.io/Bnaya/pen/EoJlb

JS:

(function () {
    'use strict';

    if (!('addEventListener' in window)) {
        return;
    }

    var htmlElement = document.querySelector('html');

    function touchStart () {
        document.querySelector('html').classList.remove('hover-active');

        htmlElement.removeEventListener('touchstart', touchStart);
    }

    htmlElement.addEventListener('touchstart', touchStart);
}());

HTML:

<html class="hover-active">

CSS:

.hover-active .mybutton:hover {
    box-shadow: 1px 1px 1px #000;
}

Invece di ascoltare un evento touch, puoi provare 'ontouchstart' in window. ad esempioif ('ontouchstart' in window) document.querySelector('html').classList.remove('hover-active');
Yuval A.

@YuvalA. Il motivo per cui sto aspettando l'evento di tocco è che ci sono dispositivi con puntatore e supporto per il tocco e l'utente sta utilizzando il puntatore non voglio rimuovere il passaggio del mouse. È possibile che l'utente utilizzi il tocco e quindi il puntatore, ma non ho molto da fare al riguardo
Bnaya

2

Quello che ho fatto per risolvere lo stesso problema è avere una funzione di rilevamento (io uso qualcosa di simile a questo codice ), vedendo se onTouchMove è definito, e se è così aggiungo la classe css "touchMode" al corpo, altrimenti aggiungo " desktopMode".

Quindi ogni volta che un effetto di stile si applica solo a un dispositivo touch, o solo a un desktop, la regola css viene anteposta con la classe appropriata:

.desktopMode .someClass:hover{ color: red }
.touchMode .mainDiv { width: 100%; margin: 0; /*etc.*/ }

Modifica : questa strategia ovviamente aggiunge alcuni caratteri extra al tuo css, quindi se sei preoccupato per la dimensione del css, puoi cercare le definizioni touchMode e desktopMode e metterle in file diversi, in modo da poter servire css ottimizzato per ogni dispositivo genere; oppure potresti cambiare i nomi delle classi in qualcosa di molto più breve prima di andare a prod.


2

Bene, ho avuto un problema simile ma sono riuscito a risolverlo con media query e semplici CSS. Sono sicuro di infrangere alcune regole qui, ma per me funziona.

Fondamentalmente ho dovuto prendere una massiccia applicazione creata da qualcuno e renderla reattiva. Hanno usato jQueryUI e mi hanno chiesto di non manomettere nessuno dei loro jQuery, quindi ero limitato a usare solo CSS.

Quando ho premuto uno dei loro pulsanti in modalità touchscreen, l'effetto hover si attivava per un secondo prima che l'azione del pulsante avesse effetto. Ecco come l'ho risolto.

@media only screen and (max-width:1024px) {

       #buttonOne{
            height: 44px;
        }


        #buttonOne:hover{
            display:none;
        }
}   

2

Nel mio progetto abbiamo risolto questo problema utilizzando https://www.npmjs.com/package/postcss-hover-prefix e https://modernizr.com/ Per prima cosa abbiamo post-elaborato i file CSS di output con postcss-hover-prefix. Aggiunge .no-touchper tutte le hoverregole CSS .

const fs = require("fs");
const postcss = require("postcss");
const hoverPrfx = require("postcss-hover-prefix");

var css = fs.readFileSync(cssFileName, "utf8").toString();
postcss()
   .use(hoverPrfx("no-touch"))
   .process(css)
   .then((result) => {
      fs.writeFileSync(cssFileName, result);
   });

css

a.text-primary:hover {
  color: #62686d;
}

diventa

.no-touch a.text-primary:hover {
  color: #62686d;
}

In fase Modernizrdi esecuzione aggiunge automaticamente classi CSS a htmltag in questo modo

<html class="wpfe-full-height js flexbox flexboxlegacy canvas canvastext webgl 
  no-touch 
  geolocation postmessage websqldatabase indexeddb hashchange
  history draganddrop websockets rgba hsla multiplebgs backgroundsize borderimage
  borderradius boxshadow textshadow opacity cssanimations csscolumns cssgradients
  cssreflections csstransforms csstransforms3d csstransitions fontface
  generatedcontent video audio localstorage sessionstorage webworkers
  applicationcache svg inlinesvg smil svgclippaths websocketsbinary">

Tale post-elaborazione di CSS plus Modernizr disabilita il passaggio del mouse per i dispositivi touch e abilita gli altri. In effetti questo approccio è stato ispirato da Bootstrap 4, come risolvono lo stesso problema: https://v4-alpha.getbootstrap.com/getting-started/browsers-devices/#sticky-hoverfocus-on-mobile


1

Puoi attivare l' mouseLeaveevento ogni volta che tocchi un elemento sul touchscreen. Ecco una soluzione per tutti i <a>tag:

function removeHover() {
    var anchors = document.getElementsByTagName('a');
    for(i=0; i<anchors.length; i++) {
        anchors[i].addEventListener('touchstart', function(e){
            $('a').mouseleave();
        }, false);
    }
}

JSHint dice "non creare funzioni all'interno di un ciclo".
NetOperator Wibby

È un trucco. NON è un codice riutilizzabile che può essere considerato una buona pratica. @NetOperatorWibby
Ha detto Kholov il

Beh, non è molto utile pubblicare codice che non può essere considerato una buona pratica. È come mettere un cerotto su una ferita da coltello.
NetOperator Wibby

1

Iv aveva trovato 2 soluzioni al problema, il che implica che si rileva il tocco con modernizr o qualcos'altro e si imposta una classe di tocco sull'elemento html.

Questo è buono ma non supportato molto bene:

html.touch *:hover {
    all:unset!important;
}

Ma questo ha un ottimo supporto :

html.touch *:hover {
    pointer-events: none !important;
}

Funziona perfettamente per me, fa in modo che tutti gli effetti al passaggio del mouse siano come quando si tocca un pulsante si accende ma non finisce per essere buggato come effetto di passaggio del mouse iniziale per gli eventi del mouse.

Rilevando il tocco da dispositivi no-touch penso che modernizr abbia fatto il lavoro migliore:

https://github.com/Modernizr/Modernizr/blob/master/feature-detects/touchevents.js

MODIFICARE

Ho trovato una soluzione migliore e più semplice a questo problema

Come determinare se il client è un dispositivo touch


0

Potrebbe essere utile vedere il tuo CSS, poiché sembra un problema piuttosto strano. Ma comunque, se sta accadendo e tutto il resto va bene, potresti provare a spostare l'effetto hover su javascript (potresti usare anche jquery). Associa semplicemente l'evento mouseover o, meglio ancora, mouseenter e illumina il tuo elemento quando l'evento si attiva.

Controlla l'ultimo esempio qui: http://api.jquery.com/mouseover/ , potresti usare qualcosa di simile per registrare quando l'evento si attiva e prenderlo da lì!


Niente di speciale nel CSS; vedere la mia modifica. E ho già provato mouseenter; niente da fare. Toccando si sposta il "cursore invisibile del mouse", quindi si attiva mouseentere mousemove(e mouseleavequando si tocca da qualche altra parte).
Joe White

0

Se sei felice di usare JavaScript, puoi usare Modernizr nella tua pagina. Quando la pagina viene caricata, un browser non touch screen avrà la classe ".no-touch" aggiunta al tag html, ma per un browser touch screen, il tag html avrà la classe ".touch" aggiunta al tag html .

Quindi è semplicemente un caso di verificare se il tag html ha la classe no-touch prima di decidere di aggiungere il mouseenter e gli ascoltatori mouseleave.

if($('html').hasClass('no-touch')){
    $('.box').on("mouseenter", function(event){
            $(this).css('background-color','#0000ff')
    });
    $('.box').on("mouseleave", function(event){
            $(this).css('background-color','')
    });
}

Per un dispositivo touchscreen gli eventi non avranno ascoltatori, quindi non otterrai alcun effetto al passaggio del mouse quando tocchi.


Quando può essere fatto con CSS, non usare javascript (jquery) è uno spreco di potenza del computer
Simon Dragsbæk

1
Ancora più semplice, nel tuo CSS, potresti definire regole separate per .touche .no-touch. Riscrivere la tua risposta in CSS insieme a Modernizer html.no-touch .box:hover {background-color: "#0000ff"}e non definire nulla per html.touch .box:hoverdovrebbe fare il trucco, poiché l'OP sta solo cercando di evitare i dispositivi mobili :hover.
Walter Roman

0

In un progetto che ho fatto di recente, ho risolto questo problema con la funzione eventi delegati di jQuery. Cerca determinati elementi utilizzando un selettore jQuery e aggiunge / rimuove una classe CSS a quegli elementi quando il mouse si trova sopra l'elemento. Sembra funzionare bene per quanto sono stato in grado di testarlo, che include IE10 su un notebook con funzionalità touch con Windows 8.

$(document).ready(
    function()
    {
        // insert your own selector here: maybe '.hoverable'?
        var selector = 'button, .hotspot';

        $('body')
            .on('mouseover', selector, function(){ $(this).addClass('mouseover');    })
            .on('mouseout',  selector, function(){ $(this).removeClass('mouseover'); })
            .on('click',     selector, function(){ $(this).removeClass('mouseover'); });
    }
);

modifica: questa soluzione, ovviamente, richiede che tu modifichi il tuo CSS per rimuovere i selettori ": hover" e contemplare in anticipo su quali elementi vuoi essere "hoverable".

Se hai molti elementi sulla tua pagina (come diverse migliaia) potrebbe diventare un po 'lento, però, perché questa soluzione cattura eventi di tre tipi su tutti gli elementi nella pagina, e poi fa la sua cosa se il selettore corrisponde. Ho chiamato la classe CSS "mouseover" invece di "hover", perché non volevo che nessun lettore CSS leggesse ": hover" dove ho scritto ".hover".


0

Ecco la mia soluzione: http://jsfiddle.net/agamemnus/g56aw709/-- codice qui sotto.

Tutto quello che devi fare è convertire il loro ": hover" in ".hover" ... questo è tutto! La grande differenza tra questo e il resto è che questo funzionerà anche su selettori di elementi non singolari come .my_class > *:hover {.

handle_css_hover_effects ()

function handle_css_hover_effects (init) {
 var init = init || {}
 var handle_touch_events = init.handle_touch_events || true
 var handle_mouse_events = init.handle_mouse_events || true
 var hover_class         = init.hover_class         || "hover"
 var delay_preferences   = init.delay_preferences   || {touch: {add: 500, remove: 500}}
 function default_handler (curobj, input_type, op) {
  var hovered_element_selector = "*" + ((op == "add") ? ":" : ("." + hover_class))
  var hovered_elements = Array.prototype.slice.call(document.body.querySelectorAll(hovered_element_selector))
  var modified_list = []
  while (true) {
   if ((curobj == null) || (curobj == document.documentElement)) break
   if (hovered_elements.indexOf(curobj) != -1) modified_list.push (curobj)
   curobj = curobj.parentNode
  }
  function do_hover_change () {modified_list.forEach (function (curobj) {curobj.classList[op](hover_class)})}
  if ((!delay_preferences[input_type]) || (!delay_preferences[input_type][op])) {
   do_hover_change ()
  } else {
   setTimeout (do_hover_change, delay_preferences[input_type][op])
  }
 }

 if (handle_mouse_events) {
  document.body.addEventListener ('mouseover' , function (evt) {var curobj = evt.target; default_handler (curobj, "mouse", "add")})
  document.body.addEventListener ('mouseout'  , function (evt) {var curobj = evt.target; default_handler (curobj, "mouse", "remove")})
  document.body.addEventListener ('click'     , function (evt) {var curobj = evt.target; default_handler (curobj, "mouse", "remove")})
 }

 if (handle_touch_events) {
  document.body.addEventListener ('touchstart', function (evt) {var curobj = evt.target; default_handler (curobj, "touch", "add")})
  document.body.addEventListener ('touchend'  , function (evt) {var curobj = evt.target; default_handler (curobj, "touch", "remove")})
  document.body.addEventListener ('touchmove',  function (evt) {
   var curobj = evt.target
   var hovered_elements = Array.prototype.slice.call(document.body.querySelectorAll("*:hover"))
   var lastobj = null
   evt = evt.changedTouches[0]
   var elements_at_point = get_elements_at_point (evt.pageX, evt.pageY)
   // Get the last element that isn't at the current point but is still hovered over, and remove only its hover attribute.
   while (true) {
    if ((curobj == null) || (curobj == document.documentElement)) break
    if ((hovered_elements.indexOf(curobj) != -1) && (elements_at_point.indexOf(curobj) == -1)) lastobj = curobj
    curobj = curobj.parentNode
   }
   if (lastobj == null) return
   if ((!delay_preferences.touch) || (!delay_preferences.touch.remove)) {
    lastobj.classList.remove(hover_class)
   } else {
    setTimeout (function () {lastobj.classList.remove(hover_class)}, delay_preferences.touch.remove)
   }

   function get_elements_at_point (x, y) {
    var el_list = [], pe_list = []
    while (true) {
     var curobj = document.elementFromPoint(x, y)
     if ((curobj == null) || (curobj == document.documentElement)) break
     el_list.push (curobj); pe_list.push (curobj.style.pointerEvents)
     curobj.style.pointerEvents = "none"
    }
    el_list.forEach (function (current_element, i) {current_element.style.pointerEvents = pe_list[i]})
    return el_list
   }
  })
 }
}

0

Includi Modernizr nella tua pagina e imposta gli stati del passaggio del mouse in questo modo:

html.no-touchevents .box:hover {
    background: blue;
}

0

Ciao persona dal futuro, probabilmente vorrai usare la pointere / o la hovermedia query. La handheldmedia query è stata deprecata.

/* device is using a mouse or similar */
@media (pointer: fine) {
  a:hover {
    background: red;
  }
}

-1

Prova questa semplice soluzione jquery 2019, anche se è in giro da un po ';

  1. aggiungi questo plugin in testa:

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

  2. aggiungi questo a js:

    $("*").on("touchend", function(e) { $(this).focus(); }); //applies to all elements

  3. alcune varianti suggerite a questo sono:

    $(":input, :checkbox,").on("touchend", function(e) {(this).focus);}); //specify elements
    
    $("*").on("click, touchend", function(e) { $(this).focus(); });  //include click event`
    
    css: body { cursor: pointer; } //touch anywhere to end a focus`

Appunti

  • posizionare il plug-in prima di bootstrap.js, se applicabile, per evitare di influire sui suggerimenti
  • testato solo su iphone XR ios 12.1.12 e ipad 3 ios 9.3.5, utilizzando Safari o Chrome.

Riferimenti:

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

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.