Opóźnić zdarzenie najechania kursorem jquery?

93

Chciałbym opóźnić zdarzenie najechania kursorem w jQuery. Czytam z pliku, gdy użytkownik umieści wskaźnik myszy nad łączem lub etykietą. Nie chcę, aby to zdarzenie wystąpiło natychmiast w przypadku, gdy użytkownik porusza myszą po ekranie. Czy istnieje sposób na opóźnienie wystrzału zdarzenia?

Dziękuję Ci.

Przykładowy kod:

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

UPDATE: ( 14.01.2009 ) Po dodaniu wtyczki HoverIntent powyższy kod został zmieniony na następujący, aby go zaimplementować. Bardzo proste do wykonania.

$(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)
}
Brettski
źródło
1
Dziękujemy za udostępnienie hoverIntent
JavaKungFu,

Odpowiedzi:

91

Użyj wtyczki hoverIntent dla jquery: http://cherne.net/brian/resources/jquery.hoverIntent.html

Jest absolutnie idealny do tego, co opisujesz i używałem go w prawie każdym projekcie, który wymagał aktywacji menu najechania myszą itp.

Jest jedna pułapka do tego podejścia, niektóre interfejsy są pozbawione stanu „najechania”, np. przeglądarki mobilne, takie jak safari na iPhonie. Możesz ukrywać ważną część interfejsu lub nawigacji bez możliwości jej otwarcia na takim urządzeniu. Możesz to obejść za pomocą CSS dla konkretnego urządzenia.

roborourke
źródło
Lub ta wtyczka działa również jak urok github.com/john-terenzio/jQuery-Hover-Delay
mica
50

Musisz sprawdzić licznik czasu po najechaniu kursorem. Jeśli nie istnieje (tj. Jest to pierwszy kursor), utwórz go. Jeśli istnieje (tj. Nie jest to pierwszy kursor), wyłącz go i uruchom ponownie. Ustaw ładunek timera na swój kod.

$(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
    });
});

Założę się, że jQuery ma funkcję, która podsumowuje to wszystko za Ciebie.

Edycja : Ach tak, na ratunek wtyczka jQuery

Crescent Fresh
źródło
9
Dzięki za rozwiązanie bez wtyczki!
Jrgns
4
Dodałem clearTimeout (timer); timer = null; po stronie mouseout, ale to działało doskonale i uniknęło YAP (kolejnej wtyczki)
Andiih
@Andiih Świetna rozmowa i dzięki za wprowadzenie mnie w akronim „YAP”.
Jon
prawdopodobnie masz na myśli debounce ()
Vitim.us
11

Całkowicie się zgadzam, że hoverIntent to najlepsze rozwiązanie, ale jeśli zdarzy się, że jesteś nieszczęśliwym draniem, który pracuje na stronie internetowej z długim i przeciągającym się procesem zatwierdzania wtyczek jQuery, oto szybkie i brudne rozwiązanie, które działało dobrze:

$('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);
    }
});

Ten służy tylko do rozwijania <li>, jeśli mysz była na nim dłużej niż 300 ms.

Matthew Millman
źródło
Dzięki, uznałam to za bardziej przydatne niż inne odpowiedzi.
Ray
6

Możesz użyć wywołania setTimeout () z clearTimeout () na zdarzeniu mouseout.

Dan Monego
źródło
1

W 2016 roku rozwiązanie Crescent Fresh nie działało zgodnie z oczekiwaniami, więc wymyśliłem to:

$(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;
});
sieć
źródło
-2

Moje rozwiązanie jest łatwe. Opóźnij otwarcie menu, jeśli użytkownik przytrzyma naciśnięty przycisk myszy na obiekcie przez ponad 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);
});
onekamil
źródło