2012-08-07 17 views
14

Ho letto molti argomenti su questo argomento, un menu a discesa che è amichevole sui dispositivi mobili. Molte volte è consigliabile eseguire un'azione non al passaggio del mouse sul menu a discesa. Esistono soluzioni alternative, una delle quali indica che il collegamento ipertestuale principale per l'elemento a discesa deve essere collegato a un hashtag.Mobile (touch) menu a discesa amichevole in css/jquery

Questo funziona su dispositivi mobili, ma per il normale utente desktop, questo sarebbe fonte di confusione. Quindi la soluzione sarebbe avere un menu a discesa normale per gli utenti desktop in cui il primo collegamento ipertestuale si collega anche a una pagina. Per gli utenti mobili, il tocco su un elemento aprirà il menu a discesa, ma un secondo tocco sull'elemento principale aprirà la pagina corrispondente.

Ho visto il seguente sito e in qualche modo il loro menu funziona esattamente così: http://www.hgtv.com/ È possibile visualizzare questo su una tavoletta e fare clic sul menu principale, toccare di nuovo quella voce e si sa cosa voglio dire.

Ma come posso trovare o scaricare l'esatta configurazione simile per il mio sito?

Grazie in anticipo

+0

Hai provato "Visualizza sorgente"? Che cosa hai provato e come è fallito? – Archer

risposta

2

Si stanno per avere a gestire più eventi per ottenere tale funzionalità in entrambi i browser mobili e desktop.

Se si guarda il menu di esempio, si passa con il mouse per espandersi mentre sul cellulare si desidera un clic/tocco per espandere.

Un modo per provare a farlo sarebbe quello di avere il listener "hover" per desktop ma utilizzare un listener di eventi "touch" per dispositivi mobili.

Per fare ciò è necessario aggiungere un evento personalizzato come "touch" a jQuery. Vedere il post qui sotto di un modo per farlo:

How to recognize touch events using jQuery in Safari for iPad? Is it possible?

+0

Grazie per la vostra risposta PJH, verificherò che a breve – John

4

Ecco una tecnica indipendente dal dispositivo (non sono sicuro di quanto mi fidi del rilevamento di funzionalità per questo .. molti browser moderni riportano il supporto per gli eventi tattili anche se l'interfaccia è mouse). Ho usato per far funzionare i menu al passaggio del mouse sui touchscreen come previsto evento prematuramente "facendo clic" sul collegamento del menu principale quando vogliamo solo il primo clic t o innescare un hover).

Il trucco è riconoscere che un evento di passaggio del mouse al passaggio del mouse avverrà l'uno sopra l'altro, ovvero l'evento di passaggio del mouse verrà seguito quasi immediatamente dall'evento click. Siamo in grado di rilevare questo e impedire che il clic passi attraverso ... consentendo solo il clic per attivare se una determinata soglia di tempo è trascorso dall'evento hover.

Durante il test su un desktop, non sono mai riuscito a ottenere il tempo trascorso più velocemente di circa 150 ms tra passaggio del mouse e clic non importa quanto velocemente ho fatto clic. Durante il test su un iPad (4a gen) il tempo trascorso tra il passaggio del mouse al volo & era sempre di circa 7 - 8 ms. Quindi ho scelto un tempo limite di 50 ms per consentire il clic. La funzione jQuery che ho scritto è la seguente (questo presuppone un nested-lista del menu hover CSS standard):

function initNav(){ 
    // make drop-downs work properly with touchscreens by preventing instant hover-click 
    $(some_selector_for_your_top_level_list_items).each(function(){ 
     var li = $(this); 
     li.mouseover(function(){ 
     // store time of hover event 
     li.data('hoverTime', new Date().getTime()); 
     }); 
     li.children('a').click(function(){ 
     // only allow click if at least 50ms has elapsed since hover 
     return (new Date().getTime() - li.data('hoverTime')) > 50; 
     }); 
    }); 
    } 

Lavorare come un fascino finora.È possibile che 50 ms siano troppo bassi per dispositivi molto più lenti.

Per non-JS si avrà ancora il comportamento di hover CSS predefinito come fallback.

Spero che questo aiuti le persone, poiché non sono riuscito a trovare una buona soluzione drop-in che non includesse il rilevamento di funzionalità discutibili e/o la riscrittura del comportamento del passaggio del mouse CSS tramite JS.

+0

ho passato un po 'di tempo a cercare soluzioni diverse, ma nessuna sembrava essere pulita e affidabile. La tua soluzione funziona come un fascino, con solo un breve snippet di codice. Grazie mille per la pubblicazione! – crdunst

+0

cosa significa impedire il passaggio del mouse? sui touch screen, non c'è il cursore, quindi è impossibile "posizionare" qualsiasi cosa, non è vero? – rockyraw

+0

@rockyraw Non vedo dove ho usato la frase "prevenire il passaggio del mouse"? Il codice impedisce il passaggio di un evento CLICK. Detto questo, i browser touchscreen generano un evento "hover" falso immediatamente prima dell'evento click, che questo codice sfrutta per rilevare le differenze temporali tra l'uso del mouse e del touchscreen. – Brian

15

Ecco quello che ho ottenuto lavorando:

function isTouchDevice(){ 
    return typeof window.ontouchstart !== 'undefined'; 
} 

jQuery(document).ready(function(){ 
    /* If mobile browser, prevent click on parent nav item from redirecting to URL */ 
    if(isTouchDevice()) { 
     // 1st click, add "clicked" class, preventing the location change. 2nd click will go through. 
     jQuery("#menu-main-menu > li > a").click(function(event) { 
      // Perform a reset - Remove the "clicked" class on all other menu items 
      jQuery("#menu-main-menu > li > a").not(this).removeClass("clicked"); 
      jQuery(this).toggleClass("clicked"); 
      if (jQuery(this).hasClass("clicked")) { 
       event.preventDefault(); 
      } 
     }); 
    } 
}); 

sto usando questo per il mio sito WordPress. Sui browser desktop (browser non a tocco), quando si fa clic sulla voce del menu principale, si passa direttamente alla posizione del collegamento. Al passaggio del mouse, mostrerà il menu a discesa.

Per i dispositivi mobili (touch browser), quando si tocca la voce del menu principale, si espande il menu a discesa e, se si fa clic di nuovo, si passa alla nuova posizione. Ho anche aggiunto una riga di codice "reset" per far funzionare questa parte: se tocchi la prima voce del menu principale (espandendo il menu a discesa), tocca la seconda voce del menu principale (espandendo il secondo menu a discesa), quindi tocca il primo menu principale ancora una volta, si comporterà ancora come un elenco a discesa fino a quando non si farà nuovamente clic. Senza questa linea, procederebbe direttamente alla nuova posizione.

+0

Grazie! Proprio quello di cui avevo bisogno! –

+0

Funziona perfettamente, proprio quello che stavo cercando, grazie! –

+0

sì, questo funziona perfettamente, grazie – Cerveser