Ritardare l'evento jquery hover?


93

Vorrei ritardare un evento hover in jquery. Sto leggendo da un file quando l'utente passa il mouse su un collegamento o un'etichetta. Non voglio che questo evento si verifichi immediatamente nel caso in cui l'utente stia semplicemente spostando il mouse sullo schermo. C'è un modo per ritardare l'attivazione dell'evento?

Grazie.

Codice di esempio:

$(function() {
    $('#container a').hover(function() {
        $('<div id="fileinfo" />').load('ReadTextFileX.aspx',
            {filename:'file.txt'},
            function() {
                $(this).appendTo('#info');
            }
         );
    },
        function() { $('#info').remove(); }
    });
});

AGGIORNAMENTO: (14/01/09) Dopo aver aggiunto il plugin HoverIntent, il codice sopra è stato modificato nel seguente per implementarlo. Molto semplice da implementare.

$(function() {
    hiConfig = {
        sensitivity: 3, // number = sensitivity threshold (must be 1 or higher)
        interval: 200, // number = milliseconds for onMouseOver polling interval
        timeout: 200, // number = milliseconds delay before onMouseOut
        over: function() {
            $('<div id="fileinfo" />').load('ReadTextFileX.aspx', {filename:'file.txt'},
                function() {
                   $(this).appendTo('#info');
                }
             );
        }, // function = onMouseOver callback (REQUIRED)
        out: function() { $('#info').remove();  } // function = onMouseOut callback (REQUIRED)
    }
    $('#container a').hoverIntent(hiConfig)
}

1
Grazie per aver fornito l'utilizzo di hoverIntent
JavaKungFu

Risposte:


91

Usa il plugin hoverIntent per jquery: http://cherne.net/brian/resources/jquery.hoverIntent.html

È assolutamente perfetto per quello che descrivi e l'ho usato su quasi tutti i progetti che richiedevano l'attivazione del mouseover dei menu ecc ...

C'è un trucco in questo approccio, alcune interfacce sono prive di uno stato "hover", ad es. browser mobili come Safari su iPhone. Potresti nascondere una parte importante dell'interfaccia o della navigazione senza alcun modo per aprirla su un dispositivo del genere. Potresti aggirare questo problema con CSS specifico per dispositivo.


Oppure questo plugin funziona anche come un charm github.com/john-terenzio/jQuery-Hover-Delay
mica

50

Devi controllare un timer al passaggio del mouse. Se non esiste (cioè questo è il primo passaggio del mouse), crealo. Se esiste (cioè questo non è il primo hover), uccidilo e riavvialo. Imposta il payload del timer sul tuo codice.

$(function() {
    var timer;

    $('#container a').hover(function() {
        if(timer) {
            clearTimeout(timer);
            timer = null
        }
        timer = setTimeout(function() {
            $('<div id="fileinfo" />').load('ReadTextFileX.aspx',
                {filename:'file.txt'},
                function() {
                    $(this).appendTo('#info');
                }
            );
        }, 500)
    },
    // mouse out
    });
});

Scommetto che jQuery ha una funzione che avvolge tutto questo per te.

Modifica : Ah sì, plugin jQuery in soccorso


9
Grazie comunque per una soluzione non plug-in!
Jrgns

4
Ho aggiunto un clearTimeout (timer); timer = null; nel lato mouseout, ma ha funzionato perfettamente ed ha evitato YAP (ancora un altro plugin)
Andiih

@Andiih Grande chiamata e grazie per avermi presentato l'acronimo "YAP".
Jon,

probabilmente intendi debounce ()
Vitim.us

11

Totalmente d'accordo sul fatto che hoverIntent sia la soluzione migliore, ma se ti capita di essere uno sfortunato sod che lavora su un sito web con un processo lungo e prolungato per l'approvazione dei plugin jQuery, ecco una soluzione rapida e sporca che ha funzionato bene per me:

$('li.contracted').hover(function () {
    var expanding = $(this);
    var timer = window.setTimeout(function () {
        expanding.data('timerid', null);

            ... do stuff

    }, 300);
    //store ID of newly created timer in DOM object
    expanding.data('timerid', timer);
}, function () {
    var timerid = $(this).data('timerid');
    if (timerid != null) {
        //mouse out, didn't timeout. Kill previously started timer
        window.clearTimeout(timerid);
    }
});

Questo è solo per espandere un <li> se il mouse è stato su di esso per più di 300 ms.


Grazie, l'ho trovato più utile delle altre risposte.
Ray

6

Potresti usare una chiamata setTimeout () con clearTimeout () sull'evento mouseout.


1

Nel 2016 la soluzione di Crescent Fresh non ha funzionato come previsto per me, quindi ho pensato a questo:

$(selector).hover(function() {
    hovered = true;
    setTimeout(function() {
        if(hovered) {
            //do stuff
        }
    }, 300); //you can pass references as 3rd, 4th etc. arguments after the delay

}, function() {
    hovered = false;
});

-2

La mia soluzione è semplice. Ritarda l'apertura del menu se l'utente mantiene mouseenter su obj oltre 300 ms:

var sleep = 0;
$('#category li').mouseenter(function() {
    sleep = 1;
    $('#category li').mouseleave(function() {
        sleep = 0;
    });
    var ob = $(this);
    setTimeout(function() {                         
        if(sleep) {
            // [...] Example:
            $('#'+ob.attr('rel')).show();
        }
    }, 300);
});
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.