Il problema con il passaggio del mouse su iPad / iPhone fa sì che l'utente faccia doppio clic su un collegamento


125

Ho alcuni siti Web che ho creato qualche tempo fa, che usano eventi mouse jquery ... Ho appena ricevuto un ipad e ho notato che tutti gli eventi del mouse sugli eventi sono tradotti in clic ... quindi ad esempio devo fare due clic anziché uno .. (il primo passaggio del mouse, rispetto al clic effettivo)

c'è una soluzione alternativa pronta a risolvere questo? forse un comando jquery che avrei usato invece del mouseover / out ecc. grazie!


1
a cosa sono legati i tuoi eventi? ad esempio, gli eventi onclick dovrebbero funzionare bene ... onmouseover, onmouseout e CSS: hover sono quelli che sono un po 'difficili da gestire poiché non esiste un "hover" disponibile per un touchscreen. Hai un esempio di codice?
scunliffe,

Una cosa che ti suggerirei di fare è ripensare la tua interfaccia, se possibile. l'interazione su ipad / iphone non rispecchia esattamente quella di su un pc, ed è probabilmente una cosa saggia far sentire il tuo sito web come se fosse stato scritto per i dispositivi ipad / iphone / altri touch con meccanismi multitouch simili. Solo un pensiero.
Jer

Sono d'accordo con "jer". Questa è una domanda strana, non credo che la soluzione qui sia una "soluzione" personalmente. Penso che abbia senso tradurre un "passaggio del mouse" su un browser desktop in un "tocco delle dita" su un browser touchscreen. Se sei d'accordo con quella traduzione, ma vuoi un tocco invece di due, probabilmente farei il rilevamento delle funzionalità per gli eventi iPad (ad esempio "touchstart") e cambierei i gestori di eventi. Forse estrarre il codice in un plug-in jquery di tipo "touch or click" che si attiva in modo diverso in base alle funzionalità, ma mi sembra specifico per il tuo sito Web / app.
Andy Atkinson,

1
In realtà considero questa traduzione come una caratteristica. Se hai impostato gli eventi al passaggio del mouse, deve esserci stata qualche utilità per vederli. Un singolo tocco rivela un elemento al passaggio del mouse, un secondo tocco segue il collegamento "dietro" al passaggio del mouse.
Aaron,

Risposte:


205

Non l'ho testato completamente, ma poiché iOS genera eventi touch, questo potrebbe funzionare, supponendo che ti trovi in ​​un'impostazione jQuery.

$('a').on('click touchend', function(e) {
    var el = $(this);
    var link = el.attr('href');
    window.location = link;
});

L'idea è che Mobile WebKit genera un touchendevento alla fine di un tocco, quindi lo ascoltiamo e quindi reindirizziamo il browser non appena un touchendevento è stato attivato su un collegamento.


17
Dov'è la mia taglia? : P
cduruk,

2
Pazienza, Padwan. SO ha detto che ci vogliono 24 ore per avere effetto.
Andrew Hedges,

2
A partire da jQuery 1.7, .onè preferito .live. Dopo aver letto questa risposta, ho scoperto che cambiare il mio codice in $('a').on('click touchend', function(e) {...})funziona perfettamente.
Blazemonger,

23
Bene, questo risolve il problema iniziale, ma ne crea uno nuovo: quando si fa scorrere il dito sopra si fa clic. Questa non è una soluzione.
Luksak,

9
Questo ha i suoi difetti. Se si fa clic su un collegamento con target="_blank"esso si aprirà nella stessa finestra E in una nuova finestra.
Rybo111,

37

Non è del tutto chiaro quale sia la tua domanda, ma se vuoi semplicemente eliminare il doppio clic, pur mantenendo l'effetto hover per il mouse, il mio consiglio è di:

  • Aggiungi effetti hover su touchstarte mouseenter.
  • Rimuovere hover effetti su mouseleave, touchmovee click.

sfondo

Per simulare un mouse, browser come Webkit mobile generano i seguenti eventi se un utente tocca e rilascia un dito sul touchscreen (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 semplicemente dire al browser web di saltare gli eventi del mouse.

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

Spiegazione della soluzione

Per ricapitolare:

  • Aggiungi effetti hover su touchstarte mouseenter.
  • Rimuovere hover effetti su mouseleave, touchmovee click.

Nota che non c'è azione touchend!

Questo funziona chiaramente 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 in realtà è clickun collegamento, anche l'effetto hover viene rimosso. Ciò garantisce che venga rimosso se l'utente preme il pulsante Indietro nel browser Web.

Questo funziona anche per eventi touch: touchstartviene aggiunto l'effetto hover. È '' 'non' '' rimosso touchend. Viene nuovamente aggiunto mouseentere, poiché ciò non provoca modifiche al contenuto (era già stato aggiunto), clickviene anche generato 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 e clickviene effettivamente utilizzato perché l'effetto hover verrà mostrato in questo breve periodo.

Se l'utente decide di annullare il clic, una mossa del dito lo farà normalmente. Normalmente, questo è un problema poiché nessun mouseleaveevento viene generato e l'effetto hover rimane attivo. 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. Presuppone che un dispositivo abbia il mouse o il tocco, mentre una combinazione di entrambi diventerà sempre più comune quando i display tattili proliferano.
  • Rilevamento di supporti CSS: l'unica soluzione solo CSS di cui sono a conoscenza. È ancora soggetto a errori e presume che un dispositivo abbia il mouse o il tocco, mentre entrambi sono possibili.
  • Emula l'evento click in touchend: Questo seguirà erroneamente il link, anche se l'utente volesse solo scorrere o ingrandire, senza l'intenzione di fare effettivamente clic sul link.
  • Usa una variabile per sopprimere gli eventi del mouse: imposta una variabile touchendche viene utilizzata come una condizione if negli eventi successivi del mouse per impedire cambiamenti di stato in quel momento. La variabile viene ripristinata nell'evento click. 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 generato (ad esempio l'utente ha fatto scorrere o ingrandito), e successivamente sta cercando di seguire il collegamento con un mouse (cioè su un dispositivo con mouse e interfaccia touch ).

Ulteriori letture

Vedi anche il problema del doppio clic di iPad / iPhone e disabilita gli effetti hover sui browser mobili .


2
sembra la migliore spiegazione per coloro che desiderano una soluzione più che corretta. Grazie
antiplayer

Un ringraziamento speciale per le informazioni sul colore backround per> iOS7. Ho trascorso un po 'di tempo cercando di capire quando questo ha iniziato a funzionare.
staffang

20

Sembra che ci sia una soluzione CSS dopo tutto. Il motivo per cui Safari attende un secondo tocco è dovuto all'immagine (o agli elementi) di sfondo che di solito assegni all'evento: hover. Se non c'è nessuno da mostrare, non avrai problemi. La soluzione è quella di indirizzare la piattaforma iOS con file CSS secondario (o stile nel caso di un approccio JS) che prevale: passa il mouse sullo sfondo per ereditare, ad esempio, e tenere nascosti gli elementi che avresti visualizzato al passaggio del mouse:

Ecco un esempio di CSS e HTML - un blocco di prodotti con un'etichetta stellata al passaggio del mouse:

HTML:

<a href="#" class="s"><span class="s-star"></span>Some text here</a>

CSS:

.s {
   background: url(some-image.png) no-repeat 0 0;

}
.s:hover {
   background: url(some-image-r.png) no-repeat 0 0;
}

.s-star {
   background: url(star.png) no-repeat 0 0;
   height: 56px;
   position: absolute;
   width: 72px;
   display:none;
}

.s:hover .s-star {
   display:block;
}

Soluzione (CSS secondario):

/* CSS */
/* Keep hovers the same or hidden */
.s:hover {
   background:inherit;
}
.s:hover .s-star {
   display:none;
}


Questa risposta è orientata verso immagini di sfondo ma hai una soluzione per semplici cambiamenti di opacità? Questa soluzione non funziona per questo.
Ian S

5

Non c'è bisogno di rendere troppo complicato.

$('a').on('touchend', function() {
    $(this).click();
});

5

Ciò che ha funzionato per me è ciò che altri hanno già detto:

Non mostrare / nascondere elementi su hover o mousemove (che è l'evento nel mio caso).

Ecco cosa dice Apple ( https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html ):

Un elemento selezionabile è un collegamento, un elemento modulo, un'area della mappa immagine o qualsiasi altro elemento con gestori mousemove, mousedown, mouseup o onclick

Se l'utente tocca un elemento selezionabile, gli eventi arrivano in questo ordine: mouseover, mousemove, mousedown, mouseup e click. Inoltre, se il contenuto della pagina cambia nell'evento mousemove, non vengono inviati eventi successivi nella sequenza. Questo comportamento consente all'utente di toccare il nuovo contenuto.

Quindi, è possibile utilizzare la soluzione di @ woop: rilevare userAgent, verificare se si tratta del dispositivo iOS e quindi associare l'evento. Ho finito per usare questa tecnica perché si adatta alle mie esigenze e ha più senso non legare eventi hover quando non lo vuoi.

Ma ... se non vuoi fare confusione con userAgents e ancora nascondere / mostrare elementi su hover / mousemove, ho scoperto che puoi farlo usando javascript nativo, in questo modo:

$("body").on("mouseover", function() {
       document.getElementsByTagName("my-class")[0].style.display = 'block'; //show element
       document.querySelector(".my-selector div").style.display = 'none'; // hide element
});

Funzionerà sulla versione desktop e non farà nulla sulla versione mobile.

E per un po 'più di compatibilità ...

$("body").on("mouseover", function() {
   if (document.getElementsByTagName && document.querySelector) { // check compatibility
       document.getElementsByTagName("my-class")[0].style.display = 'block'; //show element
       document.querySelector(".my-selector div").style.display = 'none'; // hide element
    } else {
        $(".my-class").show();
        $(".my-selector div").hide();
    }
});

1
Quel bit "se il contenuto della pagina cambia sull'evento mousemove, non vengono inviati eventi successivi nella sequenza" lo ha fatto davvero per me. Avevo una pagina in cui i collegamenti di intestazione avrebbero richiesto un doppio tocco in cui i pulsanti nel contenuto (con tutte le transizioni css3 felici su em) avrebbero richiesto un solo tocco. È apparso che i collegamenti di intestazione avevano uno pseudo-elemento che passava dall'opacità: 0 all'opacità: 1 al passaggio del mouse. La rimozione di tale effetto ha risolto immediatamente il problema e ho trovato una soluzione CSS per ottenere ancora l'aspetto desiderato.
Falso Haak il

3

La soluzione di cduruk è stata abbastanza efficace, ma ha causato problemi in alcune parti del mio sito. Poiché stavo già usando jQuery per aggiungere la classe hover CSS, la soluzione più semplice era semplicemente non aggiungere la classe hover CSS sui dispositivi mobili (o più precisamente, aggiungerla SOLO quando NON su un dispositivo mobile).

Ecco l'idea generale:

var device = navigator.userAgent.toLowerCase();
var ios = device.match(/(iphone|ipod|ipad)/);

if (!(ios)) {
    $(".portfolio-style").hover(
        function(){
            $(this).stop().animate({opacity: 1}, 100);
            $(this).addClass("portfolio-red-text");
        },
        function(){
            $(this).stop().animate({opacity: 0.85}, 100);
            $(this).removeClass("portfolio-red-text");
        }
    );
}

* codice ridotto a scopo illustrativo


1
Questa è chiaramente la risposta. Le altre "soluzioni" non risolvono il problema. Safari iOS è chiaramente imperfetto nel pensare che vogliamo prima passare il mouse. Altri sistemi operativi hanno funzioni di passaggio del mouse effettive quando si passa con il mouse su un elemento.
Joshua Pack,

Questa è stata l'unica cosa che ha funzionato per me. Grazie mille!
tx291,

2

Penso che sarebbe saggio provare mouseenteral posto di mouseover. È ciò che viene utilizzato internamente quando si esegue il binding .hover(fn,fn)ed è generalmente ciò che si desidera.


1

Ho avuto i seguenti problemi con le soluzioni esistenti e ho trovato qualcosa che sembra risolverli tutti. Questo presuppone che tu stia mirando a qualcosa tra browser, dispositivo e non desideri che il dispositivo si annusi.

I problemi che questo risolve

Utilizzando solo touchstarto touchend:

  • Fa sì che l'evento si attivi quando le persone stanno provando a scorrere oltre il contenuto e si è appena verificato che questo elemento ha il dito su questo elemento quando iniziano a scorrere, attivando l'azione in modo imprevisto.
  • Può causare l' attivazione dell'evento su longpress , simile al clic destro sul desktop. Ad esempio, se l'evento click passa all'URL X e l'utente preme a lungo per aprire X in una nuova scheda, l'utente sarà confuso nel trovare X aperta in entrambe le schede. Su alcuni browser (ad es. IPhone) potrebbe anche impedire la visualizzazione del menu a pressione prolungata.

Triggering mouseovereventi on touchstarte mouseouton touchmoveha meno gravi conseguenze, ma non interferisce con il solito comportamento del browser, ad esempio:

  • Una lunga pressione innescherebbe un passaggio del mouse che non finisce mai.
  • Molti browser Android trattano la posizione del dito su touchstartcome un mouseover, che viene mouseoutedito il prossimo touchstart. Un modo per vedere il contenuto del mouseover su Android è quindi toccare l'area di interesse e muovere il dito, scorrendo leggermente la pagina. Trattare touchmovecome si mouseoutrompe questo.

La soluzione

In teoria, potresti semplicemente aggiungere una bandiera touchmove, ma gli iPhone attivano il touchmove anche se non c'è movimento. In teoria, si può solo confrontare la touchstarte touchenddell'evento pageXe pageY , ma su iPhone, non c'è touchend pageXopageY .

Quindi purtroppo per coprire tutte le basi finisce un po 'più complicato.

$el.on('touchstart', function(e){
    $el.data('tstartE', e);
    if(event.originalEvent.targetTouches){
        // store values, not reference, since touch obj will change
        var touch = e.originalEvent.targetTouches[0];
        $el.data('tstartT',{ clientX: touch.clientX, clientY: touch.clientY } );
    }
});
$el.on('touchmove', function(e){
    if(event.originalEvent.targetTouches){
        $el.data('tstartM', event.originalEvent.targetTouches[0]);
    }
});

$el.on('click touchend', function(e){
    var oldE = $el.data('tstartE');
    if( oldE && oldE.timeStamp + 1000 < e.timeStamp ) {
        $el.data('tstartE',false);
        return;
    }
    if( $el.data('iosTouchM') && $el.data('tstartT') ){
        var start = $el.data('tstartT'), end = $el.data('tstartM');
        if( start.clientX != end.clientX || start.clientY != end.clientY ){
            $el.data('tstartT', false);
            $el.data('tstartM', false);
            $el.data('tstartE',false);
            return;
        }
    }
    $el.data('tstartE',false);

In teoria, ci sono modi per ottenere il tempo esatto usato per un longpress invece di usare solo 1000 come approssimazione, ma in pratica non è così semplice ed è meglio usare un proxy ragionevole .


1

La risposta di MacFreak mi è stata estremamente utile. Ecco un po 'di codice pratico nel caso ti aiuti.

PROBLEMA - l'applicazione del touchend significa ogni volta che fai scorrere il dito su un elemento, risponde come se lo avessi premuto, anche se stavi solo cercando di scorrere.

Sto creando un effetto con jQuery che sfuma una linea sotto alcuni pulsanti per "evidenziare" il pulsante al passaggio del mouse. Non voglio che ciò significhi che è necessario premere due volte il pulsante sui dispositivi touch per seguire il collegamento.

Ecco i pulsanti:

<a class="menu_button" href="#">
    <div class="menu_underline"></div>
</a>

Voglio che il div "menu_underline" si dissolva al passaggio del mouse e si dissolva al passaggio del mouse. MA voglio che i dispositivi touch siano in grado di seguire il link con un solo clic, non due.

SOLUZIONE - Ecco il jQuery per farlo funzionare:

//Mouse Enter
$('.menu_button').bind('touchstart mouseenter', function(){
    $(this).find(".menu_underline").fadeIn();
});

//Mouse Out   
$('.menu_button').bind('mouseleave touchmove click', function(){
    $(this).find(".menu_underline").fadeOut();
});

Mille grazie per l'aiuto su questo MacFreak.


1

Ho appena scoperto che funziona se aggiungi un ascoltatore vuoto, non chiedermi perché, ma l'ho testato su iPhone e iPad con iOS 9.3.2 e ha funzionato bene.

if(/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream){
    var elements = document.getElementsByTagName('a');
    for(var i = 0; i < elements.length; i++){
        elements[i].addEventListener('touchend',function(){});
    }
}


0

Ho avuto lo stesso problema ma non su un dispositivo touch. L'evento si attiva ogni volta che fai clic. C'è qualcosa sull'accodamento degli eventi o giù di lì.

Tuttavia, la mia soluzione era così: all'evento click (o touch?) Hai impostato un timer. Se si fa di nuovo clic sul collegamento entro X ms, si restituisce semplicemente false.

Per impostare il timer per elemento, è possibile utilizzare $.data().

Questo può anche risolvere il problema @Ferdy sopra descritto.


Puoi pubblicare come appare questo codice? Sto riscontrando questo problema di attivazione dell'evento clic due volte.
fantasia

0

Se usi Modernizr, è molto facile usare Modernizr.touch come menzionato in precedenza.

Tuttavia, preferisco usare una combinazione di Modernizr.touch e test dell'agente utente, solo per sicurezza.

var deviceAgent = navigator.userAgent.toLowerCase();

var isTouchDevice = Modernizr.touch || 
(deviceAgent.match(/(iphone|ipod|ipad)/) ||
deviceAgent.match(/(android)/)  || 
deviceAgent.match(/(iemobile)/) || 
deviceAgent.match(/iphone/i) || 
deviceAgent.match(/ipad/i) || 
deviceAgent.match(/ipod/i) || 
deviceAgent.match(/blackberry/i) || 
deviceAgent.match(/bada/i));

function Tipsy(element, options) {
    this.$element = $(element);
    this.options = options;
    this.enabled = !isTouchDevice;
    this.fixTitle();
};

Se non usi Modernizr, puoi semplicemente sostituire la Modernizr.touchfunzione sopra con('ontouchstart' in document.documentElement)

Si noti inoltre che testare l'agente utente iemobile offrirà una gamma più ampia di dispositivi mobili Microsoft rilevati rispetto a Windows Phone.


0

Puoi usare click touchend,

esempio:

$('a').on('click touchend', function() {
    var linkToAffect = $(this);
    var linkToAffectHref = linkToAffect.attr('href');
    window.location = linkToAffectHref;
});

L'esempio sopra influirà su tutti i collegamenti sui dispositivi touch.

Se desideri scegliere come target solo collegamenti specifici, puoi farlo impostando una classe su di essi, ovvero:

HTML:

<a href="example.html" class="prevent-extra-click">Prevent extra click on touch device</a>

jquery:

$('a.prevent-extra-click').on('click touchend', function() {
    var linkToAffect = $(this);
    var linkToAffectHref = linkToAffect.attr('href');
    window.location = linkToAffectHref;
});

Saluti,

Jeroen


0

Mi sono imbattuto in una situazione simile in cui avevo eventi associati agli stati mouseenter / mouseleave / click di un elemento, ma su un iPhone, l'utente doveva fare doppio clic sull'elemento per innescare prima l'evento mouseenter, quindi di nuovo per lanciare l'evento click .

Ho risolto questo problema usando un metodo simile come sopra, ma ho fatto uso del plugin jQuery $ .browser (per jQuery 1.9>) e ho aggiunto un evento .trigger all'evento di associazione del mouseenter, come segue:

// mouseenter event
$('.element').on( "mouseenter", function() {
    // insert mouseenter events below

    // double click fix for iOS and mouseenter events
    if ($.browser.iphone || $.browser.ipad) $(this).trigger('click');
});
// mouseleave event
$('.element').on( "mouseleave", function() { 
    // insert mouseout events below
});
// onclick event
$('.element').on( "click", function() {
    // insert click events below
});

.Trigger evita la necessità di fare doppio clic sull'elemento attivando il gestore eventi .click sul mouseenter (o clic iniziale) dell'elemento quando viene visualizzato su iPhone o iPad. Potrebbe non essere la soluzione più elegante, ma funziona perfettamente nel mio caso e utilizza un plug-in che avevo già installato e mi ha richiesto di aggiungere una singola riga di codice per far funzionare i miei eventi esistenti con questi dispositivi.

Puoi ottenere il plugin jQuery $ .browser qui: https://github.com/gabceb/jquery-browser-plugin


0

Solo un miglioramento per evitare il reindirizzamento quando si fa scorrere il dito su un collegamento per errore.

// tablet "one touch (click)" X "hover" > link redirection
$('a').on('touchmove touchend', function(e) {

    // if touchmove>touchend, set the data() for this element to true. then leave touchmove & let touchend fail(data=true) redirection
    if (e.type == 'touchmove') {
        $.data(this, "touchmove_cancel_redirection", true );
        return;
    }

    // if it's a simple touchend, data() for this element doesn't exist.
    if (e.type == 'touchend' && !$.data(this, "touchmove_cancel_redirection")) {
        var el = $(this);
        var link = el.attr('href');
        window.location = link;
    }

    // if touchmove>touchend, to be redirected on a future simple touchend for this element
    $.data(this, "touchmove_cancel_redirection", false );
});

0

Con l'ispirazione di MacFreak, ho messo insieme qualcosa che funziona per me.

Questo metodo js impedisce che l'hover si attacchi a un iPad e in alcuni casi impedisce la registrazione dei clic come due clic. In CSS, se hai qualche classe: passa il mouse su psudo classi nel tuo CSS, modificale in .hover Ad esempio .some-class: passa il mouse su .some-class.hover

Prova questo codice su un ipad per vedere come si comportano diversamente i metodi css e js hover (solo con effetto hover). Il pulsante CSS non ha un avviso di clic di fantasia. http://jsfiddle.net/bensontrent/ctgr6stm/

function clicker(id, doStuff) {
  id.on('touchstart', function(e) {
    id.addClass('hover');
  }).on('touchmove', function(e) {
    id.removeClass('hover');
  }).mouseenter(function(e) {
    id.addClass('hover');
  }).mouseleave(function(e) {
    id.removeClass('hover');
  }).click(function(e) {
    id.removeClass('hover');
    //It's clicked. Do Something
    doStuff(id);
  });
}

function doStuff(id) {
  //Do Stuff
  $('#clicked-alert').fadeIn(function() {
    $(this).fadeOut();
  });
}
clicker($('#unique-id'), doStuff);
button {
  display: block;
  margin: 20px;
  padding: 10px;
  -webkit-appearance: none;
  touch-action: manipulation;
}
.hover {
  background: yellow;
}
.btn:active {
  background: red;
}
.cssonly:hover {
  background: yellow;
}
.cssonly:active {
  background: red;
}
#clicked-alert {
  display: none;
}
<button id="unique-id" class="btn">JS Hover for Mobile devices<span id="clicked-alert"> Clicked</span>

</button>
<button class="cssonly">CSS Only Button</button>
<br>This js method prevents hover from sticking on an ipad, and prevents the click registering as two clicks. In CSS, if you have any :hover in your css, change them to .hover For example .some-class:hover to .some-class.hover


0

Per far funzionare i collegamenti senza interrompere lo scrolling del tocco, ho risolto questo problema con l'evento "tap" di jQuery Mobile:

    $('a').not('nav.navbar a').on("tap", function () {
        var link = $(this).attr('href');
        if (typeof link !== 'undefined') {
            window.location = link;
        }
    });

0

Sono troppo tardi, lo so, ma questa è una delle soluzioni più semplici che ho trovato:

    $('body').on('touchstart','*',function(){   //listen to touch
        var jQueryElement=$(this);  
        var element = jQueryElement.get(0); // find tapped HTML element
        if(!element.click){
            var eventObj = document.createEvent('MouseEvents');
            eventObj.initEvent('click',true,true);
            element.dispatchEvent(eventObj);
        }
    });

Questo non funziona solo per i collegamenti (tag di ancoraggio) ma anche per altri elementi. Spero che questo ti aiuti.


0

Questo breve frammento sembra funzionare. Attiva l'evento click quando viene toccato il link:

  $('a').on('touchstart', function() {
    $(this).trigger('click');
  });

0

Nessuna delle altre risposte funziona per me. La mia app ha molti ascoltatori di eventi, proprie caselle di controllo e collegamenti che hanno listener e collegamenti senza listener.

Io lo uso questo:

var selector = "label, a, button";
var timer;
var startX;
var startY;
$(document).on("click", selector, function (e) {
    if ($(this).data("touched") === true) {
        e.stopImmediatePropagation();
        return false;
    }
    return;
}).on("touchend", selector, function (e) {
    if (Math.abs(startX - e.originalEvent.changedTouches[0].screenX) > 10 || Math.abs(startY - e.originalEvent.changedTouches[0].screenY) > 10)
        // user action is not a tap
        return;
    var $this = $(this);
    // Visit: http://stackoverflow.com/questions/1694595/can-i-call-jquery-click-to-follow-an-a-link-if-i-havent-bound-an-event-hand/12801548#12801548
    this.click();
    // prevents double click
    $this.data("touched", true);
    if (timer)
        clearTimeout(timer);
    setTimeout(function () {
        $this.data("touched", false);
    }, 400);
    e.stopImmediatePropagation();
    return false;
}).on("touchstart", function (e) {
    startX = e.originalEvent.changedTouches[0].screenX;
    startY = e.originalEvent.changedTouches[0].screenY;
});

0

Questo funziona per me quando hai un menu a discesa jquery

if (navigator.userAgent.match(/(iPod|iPhone|iPad)/)) {
      $('.ui-autocomplete').off('menufocus hover mouseover');
}

0

Evita di cambiare lo stile di "visualizzazione" all'interno dell'evento hover css. Avevo "display: block" nello stato hover. Dopo aver rimosso iOS è andato su Lins con un solo tocco. A proposito, sembra che gli ultimi aggiornamenti di IOS abbiano risolto questa "caratteristica"


0

Il modo più semplice per risolvere il doppio clic su IPad è racchiudere il tuo CSS per l'effetto hover in query multimediali @media (pointer: fine):

@media (pointer: fine) {
  a span {
    display: none;
  }
  a:hover span {
    display: inline-block;
  }
}

I CSS inseriti in questa query multimediale verranno applicati solo sul desktop.

La spiegazione di questa soluzione è qui https://css-tricks.com/annoying-mobile-double-tap-link-issue/


-1

Puoi controllare in navigator.userAgentquesto modo:

if(!navigator.userAgent.match(/iPhone/i) || !navigator.userAgent.match(/iPad/i)) {
    //bind your mouseovers...
}

ma dovresti controllare per more, droidi, molti altri dispositivi touchscreen. Potresti anche associare i mouseover solo se userAgent contiene Mozilla, IE, Webkit o Opera, ma devi comunque cercare alcuni dispositivi perché il Droid, ad esempio, riporta la sua stringa userAgent come:

Mozilla/5.0 (Linux; U; Android 2.0.1; en-us; Droid Build/ESD56) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17

La stringa dell'iPhone è simile. Se esegui semplicemente lo schermo per iPhone, iPod, iPad, Android e Blackberry potresti ottenere la maggior parte dei palmari, ma non tutti.


Penso, per ora, per non impazzire, la cosa migliore da fare potrebbe essere solo una sceneggiatura che salta gli eventi al passaggio del mouse ... quindi immagino che la prima risposta sia stata buona ... e sì, hai ragione ... dovrei pensa a tutti gli altri dispositivi ... vorrei che Jquery o qualche plugin avessero questo tipo di funzionalità di dection ..!
Francesco,

wurfl.sourceforge.net Questa potrebbe essere la tua risposta. È un database di dispositivi wireless. Non sarà così semplice come sarebbe un plugin jQuery, ma puoi sempre scriverne uno! C'è anche tera-wurfl.com che utilizza un databse anziché un file XML. Non ho fatto molta ricerca, ma potrebbe esserci una versione ospitata là fuori, quindi non devi preoccuparti di mantenere aggiornati il ​​tuo file wurfl o il database tera-wurfl.
jasongetsdown,

1
Mi sto perdendo qualcosa o la domanda NON era di rilevare iPad, ma di aggirare un comportamento specifico su iPad?
Andrew Hedges,

5
UA annusa? Come 90: P
Macha,

-1

Basta fare una query multimediale CSS che esclude tablet e dispositivi mobili e posiziona il cursore sopra. Non hai davvero bisogno di jQuery o JavaScript per questo.

@media screen and (min-device-width:1024px) {
    your-element:hover {
        /* Do whatever here */
    }
}

E assicurati di aggiungere questo alla tua testa HTML per assicurarti che calcoli con i pixel effettivi e non con la risoluzione.

<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />
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.