2012-04-12 16 views
9

Mam użytkowników wykonujących połączenie ajax podczas pisania. Problemem jest to, że sprawia, że ​​zaproszenie do każdego listu pisanego, więc mogę ustawić limit czasu tak:Poczekaj na funkcję, aż użytkownik przestanie pisać

$(input).live('keyup', function(e){ 

setTimeout(function(){ 

var xx = $(input).val(); 
doSearch(xx); 

}, 400); 

}); 

To nie czekać na 400ms ale następnie wykonuje dla każdego keyup. Jak mogę to zmienić, aby wywoływać ajax tylko "raz" około 400 ms po ostatniej wpisanej literze?

(użyłem „opóźnienie” w przeszłości, ale to nie działa w ogóle z mojego skryptu ...)

+0

Istnieje już rozwiązanie dostarczone w innym pytaniu: https://stackoverflow.com/questions/4220126/run-javascript-function-when-user-finishes-typing-instead-of-on-key-up/16324620 # 16324620 –

Odpowiedz

18
timer = 0; 
function mySearch(){ 
    var xx = $(input).val(); 
    doSearch(xx); 
} 
$(input).live('keyup', function(e){ 
    if (timer) { 
     clearTimeout(timer); 
    } 
    timer = setTimeout(mySearch, 400); 
}); 

lepiej przenieść funkcji w nazwie funkcji i wywołać ją wiele razy, bo inaczej jesteś tworząc inną funkcję lambda na każdym keyup co jest niepotrzebne i stosunkowo drogie

+0

To zadziałało jak urok :) – Youss

+0

@Jeśli i co się stanie, jeśli naciśniesz i zwolnisz jeden klawisz, a następnie przytrzymasz kolejny klawisz? – Alnitak

+0

@Alnitak, masz rację, i są inne problemy z tym, na przykład kiedy wpisujesz zbyt wolno (ponad 400ms między 2 kluczami), ale w normalnym przypadku sprawia, że ​​rzeczy są gładsze – Gavriel

4

Trzeba zresetować licznik za każdym razem nowy klucz jest wciśnięty, na przykład

(function() { 
    var timer = null; 

    $(input).live('keyup', function(e) { 
     timer = setTimeout(..., 400); 
    }); 

    $(input).live('keydown', function(e) { 
     clearTimeout(timer); 
    }); 
)(); 

Wyrażenie Funkcja ta jest wykorzystywana w celu zapewnienia, że ​​zakres tego timer zmiennej jest ograniczony do tych dwóch funkcji, które jej potrzebują.

+0

Powinien prawdopodobnie używać '.on ('keyup', ...)' Ponieważ jquery 1.7 '.live' jest przestarzałe. – ZombieCode

+0

@Ekaterina tak, prawdopodobnie powinna, ale był to minimalny zestaw zmian kodu OP. – Alnitak

0

Myślę, że możesz może ponownie użyć w tym kontekście tak długo, jak jesteś w porządku z dodaniem nowego tymczasowego "czegoś" do miksu. Czy to działa dla ciebie?

$(input).live('keyup', function(e) { 
    if (!$(input).hasClass("outRunningAJob")) { 
     var xx = $(input).val(); 
     $(input).addClass("outRunningAJob"); 
     doSearch(xx); 
     $(input).delay(400).queue(function() { 
      $(this).removeClass("outRunningAJob"); 
      $(this).dequeue(); 
     }); 
    } 
}); 
+0

Wygląda jak obejście ... Odpowiedź udzielona przez @ Flöcsy jest bardziej prosta. ps co jest outRunningAJob :) – Youss

+0

Osobiście jeszcze nie czuję się dobrze z funkcjami 'timeout', więc pomyślałem, że może jesteś w podobnym miejscu, ponieważ pytasz o to. Czy to obejście? Tak właśnie chciałbym podejść do problemu. Jeśli obecnie lepiej znasz "opóźnienie", może to być lepsze rozwiązanie (pod względem łatwości konserwacji). "outRunningAJob" jest po prostu arbitralny, ale samopisujący. Cieszę się, że Ci się podobało :-) – veeTrain

0

znalazłem następujące łatwiejsze do wdrożenia:

$(input).on('keyup', function() { 
    delay(function() { 
     if (input).val() !== '' && $(input).val() !== $(input).attr('searchString')) { 
      // make the AJAX call at this time 
      // Store the value sent so we can compare when JSON returns 
      $(input).attr('searchString', $(input).val()); 

      namepicker2_Search_Prep(input); 
     } 
    }, 500); 
}); 

Dzięki przechowywaniu bieżący ciąg jesteś w stanie zobaczyć, że użytkownik przestał pisać. Następnie możesz bezpiecznie wywołać swoją funkcję, aby zrobić to, co kiedykolwiek musi się wydarzyć.

Powiązane problemy