Verzögern Aktionen zwischen keypress in jQuery
Frage
Wie kann ich verzögern Aktionen zwischen keypress in jQuery. Zum Beispiel:
Ich habe so etwas wie diese
if($(this).val().length > 1){
$.post("stuff.php", {nStr: "" + $(this).val() + ""}, function(data){
if(data.length > 0) {
$('#suggestions').show();
$('#autoSuggestionsList').html(data);
}else{
$('#suggestions').hide();
}
});
}
Ich möchte verhindern, dass Daten veröffentlichen, wenn der Benutzer kontinuierlich eingeben. So wie kann ich geben 0,5 Sekunden Verzögerung?
Lösung
Sie können jQuery Daten Fähigkeiten, dies zu tun, so etwas wie folgt aus:
$('#mySearch').keyup(function() {
clearTimeout($.data(this, 'timer'));
var wait = setTimeout(search, 500);
$(this).data('timer', wait);
});
function search() {
$.post("stuff.php", {nStr: "" + $('#mySearch').val() + ""}, function(data){
if(data.length > 0) {
$('#suggestions').show();
$('#autoSuggestionsList').html(data);
}else{
$('#suggestions').hide();
}
});
}
Der Hauptvorteil ist hier keine globalen Variablen alle über den Platz, und man kann dies in einer anonymen Funktion in der setTimeout wickelt, wenn man wollte, nur das Beispiel so sauber wie möglich zu machen versuchen.
Andere Tipps
Alles, was Sie tun müssen, ist Ihre Funktion in einem Timeout wickeln, die zurückgesetzt wird, wenn der Benutzer eine Taste drückt:
var ref;
var myfunc = function(){
ref = null;
//your code goes here
};
var wrapper = function(){
window.clearTimeout(ref);
ref = window.setTimeout(myfunc, 500);
}
Dann einfach aufrufen "Wrapper" in Ihrem Schlüsselereignis.
Es gibt ein schönes Plugin, dies zu umgehen. jQuery Gas / Debounce
Nick Antwort ist perfekt, aber wenn sofort erste Event-Handling entscheidend ist, dann denke ich, dass wir tun können:
$(selector).keyup(function(e){ //or another event
if($(this).val().length > 1){
if !($.data(this, 'bouncing-locked')) {
$.data(this, 'bouncing-locked', true)
$.post("stuff.php", {nStr: "" + $(this).val() + ""}, function(data){
if(data.length > 0) {
$('#suggestions').show();
$('#autoSuggestionsList').html(data);
}else{
$('#suggestions').hide();
}
});
self = this
setTimeout(function() {
$.data(self, 'bouncing-locked', false);
//in case the last event matters, be sure not to miss it
$(this).trigger("keyup"); // call again the source event
}, 500)
}
}
});
Ich würde wickeln Sie es in einer Funktion wie so:
var needsDelay = false;
function getSuggestions(var search)
{
if(!needsDelay)
{
needsDelay = true;
setTimeout("needsDelay = false", 500);
if($(this).val().length > 1){
$.post("stuff.php", {nStr: "" + search + ""}, function(data){
if(data.length > 0) {
$('#suggestions').show();
$('#autoSuggestionsList').html(data);
}else{
$('#suggestions').hide();
}
});
}
}
}
Auf diese Weise unabhängig davon, wie oft Sie diese anpingen, werden Sie nie mehr als alle 500 Millisekunden suchen.