2009-07-06 13 views
48

Ho un menu a discesa. Ora, quando viene spostato su più livelli, mi piacerebbe aggiungere tempo di attesa per 2 secondi, prima che scompaia, in modo che l'utente possa rientrare, quando si rompe lo .hover() per errore.Come dire a .hover() di aspettare?

È possibile?

mio codice per la diapositiva:

$('.icon').hover(function() { 
     $('li.icon > ul').slideDown('fast'); 
    }, function() { 
     $('li.icon > ul').slideUp('fast'); 
    }); 

risposta

74

Questo renderà la seconda funzione attendere 2 secondi (2000 millisecondi) prima di eseguire:

$('.icon').hover(function() { 
    clearTimeout($(this).data('timeout')); 
    $('li.icon > ul').slideDown('fast'); 
}, function() { 
    var t = setTimeout(function() { 
     $('li.icon > ul').slideUp('fast'); 
    }, 2000); 
    $(this).data('timeout', t); 
}); 

Si cancella anche il timeout quando l'utente passa indietro per evitare comportamenti pazzi.

Questo non è un modo molto elegante per farlo, tuttavia. Probabilmente dovresti controllare il plugin hoverIntent, che è stato progettato per risolvere questo particolare problema.

+0

$ (this) .data? Sembra che io abbia qualche lettura da fare! –

+8

+1 per hoverIntent! – alex

+0

Questa dovrebbe essere la prima risposta. – Ronan

1

L'idea generale è quella di utilizzare setTimeout, in questo modo:

$('.icon').hover(function() { 
      $('li.icon > ul').slideDown('fast'); 
    }, function() { 
      setTimeout(function() { 
       $('li.icon > ul').slideUp('fast'); 
      }, 2000); 
    }); 

Ma questo può fare cose controintuitive se l'utente posiziona il mouse e poi Mouses di nuovo rapidamente-questo non tiene conto di compensazione quando il timeout l'utente passa di nuovo su di esso. Ciò richiederebbe uno stato aggiuntivo.

42

personalmente mi piace il plugin "hoverIntent":

http://cherne.net/brian/resources/jquery.hoverIntent.html

dalla pagina: hoverIntent è un plugin che tenta di determinare l'intenzione dell'utente ... come una sfera di cristallo, solo con il mouse movimento! Funziona come (ed è stato derivato da) hover incorporato di jQuery. Tuttavia, invece di chiamare immediatamente la funzione onMouseOver, attende che il mouse dell'utente rallenti abbastanza prima di effettuare la chiamata.

Perché? Per ritardare o impedire lo sparo accidentale di animazioni o chiamate ajax. I timeout semplici funzionano per aree piccole, ma se l'area di destinazione è ampia, può essere eseguita indipendentemente dall'intento.

var config = {  
sensitivity: 3, // number = sensitivity threshold (must be 1 or higher)  
interval: 200, // number = milliseconds for onMouseOver polling interval  
over: makeTall, // function = onMouseOver callback (REQUIRED)  
timeout: 500, // number = milliseconds delay before onMouseOut  
out: makeShort // function = onMouseOut callback (REQUIRED) 
}; 
$("#demo3 li").hoverIntent(config) 

Opzioni di configurazione

sensibilità: Se il mouse si sposta meno di questo numero di pixel tra intervalli di polling, quindi la funzione "over" sarà chiamato. Con la soglia minima di sensibilità di 1, il mouse non deve spostarsi tra gli intervalli di polling. Con soglie di sensibilità più elevate è più probabile che riceviate un falso positivo. sensibilità predefinita: 7

intervallo: Il numero di millisecondi hoverIntent attende tra lettura/confronto coordinate del mouse. Quando il mouse dell'utente entra per la prima volta nell'elemento, le sue coordinate vengono registrate. Il più presto possibile la funzione "sopra" può essere chiamato dopo un singolo intervallo di polling. Impostando l'intervallo di polling più alto si aumenta il ritardo prima della prima possibile chiamata "sopra", ma si aumenta anche il tempo al successivo punto di confronto. Intervallo predefinito: 100

oltre: Obbligatorio.La funzione che desideri chiamare su MouseOver. La tua funzione riceve gli stessi oggetti "this" e "event" come farebbe con il metodo hover di jQuery.

timeout: Un semplice ritardo, in millisecondi, prima che venga chiamata la funzione "out". Se l'utente torna indietro sull'elemento prima che il timeout sia scaduto, la funzione "out" non verrà chiamata (né verrà chiamata la funzione "over"). Questo è principalmente per proteggere da traiettorie di mouse mousing/sciatta che temporaneamente (e non intenzionalmente) tolgono l'utente dall'elemento bersaglio ... dando loro il tempo di tornare. Timeout predefinito: 0

out: Obbligatorio. La funzione che desideri chiamare su MouseOut. La tua funzione riceve gli stessi oggetti "this" e "event" come farebbe con il metodo hover di jQuery. Nota, hoverIntent chiamerà la funzione "out" solo se la funzione "over" è stata chiamata su quella stessa esecuzione.

+0

L'ho usato per molti anni fino a quando ho realizzato un ** overkill ** per casi come la domanda. Gli esempi di codice manuale in questo thread funzionano correttamente. –

1
$('.icon').on("mouseenter mouseleave","li.icon > ul",function(e){ 
    var $this = $(this); 
    if (e.type === 'mouseenter') { 
     clearTimeout($this.data('timeout')); 
     $this.slideDown('fast'); 
    }else{ // is mouseleave: 
     $this.data('timeout', setTimeout(function(){ 
      $this.slideUp('fast'); 
     },2000)); 
    } 
}); 
1

Di seguito si fermerà il scorrevole dalla innesco di 2 secondi:

$('.icon').hover(function() { 
    $('li.icon > ul').delay(2000).slideDown('fast'); 
}, function() { 
    $('li.icon > ul').slideUp('fast'); 
}); 
+0

Penso che questo sia sostanzialmente il contrario: l'azione di passaggio del mouse non viene attivata immediatamente, ma è necessario passare il mouse per almeno 2 secondi affinché avvenga qualcosa. Ancora utile, ma non esattamente una risposta alla domanda. Ho sbagliato? –

0

Credo che questo sia il codice il vostro bisogno:

jQuery(document).ready(function($) { 
    var navTimers = []; 
    $('.icon').hover(function() { 
      var id = jQuery.data(this); 
      var $this = $(this); 
      navTimers[id] = setTimeout(function() { 
       $this.children('ul').slideDown('fast'); 
       navTimers[id] = ""; 
      }, 300); 
     }, 
     function() { 
      var id = jQuery.data(this); 
      if (navTimers[id] != "") { 
       clearTimeout(navTimers[id]); 
      } else { 
       $(this).children("ul").slideUp('fast'); 
      } 
     } 
    ); 
}); 
0

o si può semplicemente utilizzare transizione: tutto 2s easy-in-out. assicurati di aggiungere -webkit, -moz e -o per browser diversi.

0

vorrei aggiungere a Paolo Bergantino che si può fare questo senza l'attribut dati:

var timer; 
$('.icon').hover(function() { 
    clearTimeout(timer); 
    $('li.icon > ul').slideDown('fast'); 
}, function() { 
    timer = setTimeout(function() { 
     $('li.icon > ul').slideUp('fast'); 
    }, 2000); 
}); 
0
var timer; 

var delay = 200; 

$('#hoverelement').hover(function() { 

    on mouse hover, start a timeout 

    timer = setTimeout(function() { 

     Do your stuff here 

    }, delay); 

}, function() { 

    Do mouse leaving function stuff here  

    clearTimeout(timer); 
}); 

// edit: codice instert

Problemi correlati