2009-07-06 25 views
48

Mam rozwijane menu. Teraz, gdy jest zsunięty na kilka poziomów, chciałbym dodać czas oczekiwania na 2 sekundy, zanim zniknie, więc użytkownik może wrócić przez pomyłkę, kiedy przez pomyłkę złamie .hover().Jak powiedzieć .hover() czekać?

Czy to możliwe?

mój kod na slajdzie:

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

Odpowiedz

74

uczyni to druga funkcja czekać 2 sekundy (2000 milisekund) przed wykonaniem:

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

podaje ją również limit czasu, gdy użytkownik najedzie powrotem w celu uniknięcia szalonego zachowania.

Jednak nie jest to bardzo elegancki sposób. Powinieneś prawdopodobnie sprawdzić wtyczkę hoverIntent, która ma rozwiązać ten konkretny problem.

+0

$ (this) .data? Wygląda na to, że mam coś do zrobienia! –

+8

+1 dla hoverIntent! – alex

+0

To powinna być pierwsza odpowiedź. – Ronan

1

Ogólna idea jest użycie setTimeout, tak:

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

Ale może to zrobić rzeczy sprzeczne z intuicją, gdy użytkownik najedzie na zewnątrz, a potem znowu najedzie na szybko, to nie uwzględnia wyczyszczenie limit czasu gdy jest użytkownik ponownie unosi się nad nim. To wymagałoby dodatkowego stanu.

42

osobiście lubię „hoverIntent” wtyczki:

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

ze strony: hoverIntent to plugin, który próbuje określić intencje użytkownika ... jak kryształowej kuli, tylko z myszy ruch! Działa jak (i ​​został wyprowadzony z) wbudowanego w jQuery'a hover. Jednak zamiast natychmiast wywoływać funkcję onMouseOver, czeka ona, aż mysz użytkownika zwolni wystarczająco, zanim wykona połączenie.

Dlaczego? Aby opóźnić lub zapobiec przypadkowemu odpaleniu animacji lub wywołań ajaxowych. Proste limity czasu działają na małych obszarach, ale jeśli obszar docelowy jest duży, może być wykonywany niezależnie od zamiaru.

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) 

Opcje konfiguracji

czułość: Jeśli mysz porusza się mniej niż tej liczby pikseli między odstępach wyborczych, a następnie „nad” funkcja zostanie wywołana. Przy minimalnym progu czułości 1 mysz nie może się przemieszczać między interwałami odpytywania. Przy wyższych progach czułości bardziej prawdopodobne jest otrzymanie fałszywego wyniku pozytywnego. Domyślna czułość: 7

przerwa: Liczba hoverIntent milisekund czeka między odczytem/porównaniem współrzędnych myszy. Kiedy mysz użytkownika najpierw wchodzi do elementu, jego współrzędne są rejestrowane. Najszybsza funkcja "over" może być wywołana po jednym interwale odpytywania. Ustawienie wyższej częstotliwości odpytywania zwiększy opóźnienie przed pierwszym możliwym wywołaniem "over", ale także zwiększy czas do następnego punktu porównania. Domyślny interwał: 100

przez: Wymagany.Funkcja, którą chcesz wywołać onMouseOver. Twoja funkcja otrzymuje te same obiekty "to" i "zdarzenia", co z metody kursorowej jQuery.

timeout: Proste opóźnienie, w milisekundach, przed wywołaniem funkcji "out". Jeśli użytkownik wróci z powrotem do elementu przed upływem limitu czasu, funkcja "out" nie zostanie wywołana (ani nie zostanie wywołana funkcja "over"). Ma to przede wszystkim chronić przed niechlujnymi/ludzkimi trajektoriami, które tymczasowo (i nieumyślnie) zabierają użytkownika z elementu docelowego ... dając mu czas na powrót. Domyślny limit czasu: 0

obecnie: Wymagany. Funkcja, którą chcesz wywołać onMouseOut. Twoja funkcja otrzymuje te same obiekty "to" i "zdarzenia", co z metody kursorowej jQuery. Uwaga, hoverIntent wywoła tylko funkcję "out", jeśli w tym samym przebiegu została wywołana funkcja "over".

+0

Używałem tego przez wiele lat, dopóki nie zdaję sobie sprawy z jego ** przesady ** w takich przypadkach jak pytanie. Ręczne przykłady kodu w tym wątku działają poprawnie. –

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

Poniższa zatrzyma przesuwne z wyzwalanie przez 2 sekundy:

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

Myślę, że osiąga się to w zasadzie odwrotnie: akcja najechania nie jest natychmiast uruchamiana, ale konieczne jest zatrzymanie na co najmniej 2 sekundy, aby cokolwiek się wydarzyło. Nadal przydatne, ale nie do końca odpowiedź na to pytanie. Czy się mylę? –

0

myślę, że to jest kod zapotrzebowanie:

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

lub może po prostu użyć przejścia: wszystko 2s łatwość w-out. upewnij się, że dodajesz -webkit, -moz i -o dla różnych przeglądarek.

0

Chciałbym dodać do Paolo Bergantino, że można to zrobić bez Attribut danych:

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: kod instert