2012-04-12 7 views
9

Eingabe Ich habe Benutzer Ajax-Aufruf zu machen, während Sie tippen. Das Problem ist, dass es den Anruf für jeden Buchstaben macht wird getippt, so dass ich gesetzt Timeout wie folgt aus:Warten Funktion bis Benutzer aufhört

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

setTimeout(function(){ 

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

}, 400); 

}); 

Es ist für 400 ms warten, sondern führt dann für jeden keyup. Wie kann ich das ändern, um den Ajax nur 'einmal' 400ms nach dem letzten getippten Buchstaben aufzurufen?

(I verwendet ‚Verspätung‘ in der Vergangenheit, aber das funktioniert nicht überhaupt mit meinem Skript ...)

+0

Es gibt bereits eine Lösung in anderen Fragen zur Verfügung gestellt: https://stackoverflow.com/questions/4220126/run-jacascript-function-when-user-finishes-typing-in-ont-on-key-up/16324620 # 16324620 –

Antwort

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

ist es besser, Ihre Funktion auf eine benannte Funktion zu bewegen, und es mehrmals aufrufen, denn sonst sind Sie eine weitere Lambda-Funktion auf jedem keyup zu schaffen, die nicht notwendig ist und relativ teuer

+0

, der wie ein Charme :) – Youss

+0

@Youss und was passiert, wenn Sie eine Taste drücken und loslassen, und dann nach unten einem anderen Taste gedrückt? – Alnitak

+0

@ Alnitak, Sie haben Recht, und es gibt andere Probleme mit, zum Beispiel wenn Sie zu langsam tippen (mehr als 400ms zwischen 2 Tasten), aber im Normalfall macht es die Dinge glatter – Gavriel

4

Sie müssen den Timer jedes Mal, wenn eine neue Taste gedrückt wird zurückgesetzt, z.B.

(function() { 
    var timer = null; 

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

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

Die Funktion Ausdruck wird verwendet, um sicherzustellen, dass der Anwendungsbereich der timer Variable auf diese beiden Funktionen beschränkt ist, die es brauchen.

+0

Sollte wahrscheinlich verwenden '.on ('keyup', ...)' Da jquery 1.7 '.live' ist veraltet. – ZombieCode

+0

@Ekaterina ja, sollte es wahrscheinlich, aber das war der minimale Satz von Änderungen an der OP-Code. – Alnitak

0

Ich würde denken, dass Sie konnte delay() wieder in diesem Zusammenhang verwenden, solange Sie sind ok mit dem Hinzufügen eines neuen temporären "Etwas" zum Mix. Würde das für dich funktionieren?

$(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

Scheint wie ein Workaround ... Die Antwort von @ Flöcsy ist einfacher. ps was ist outRunningAJob :) – Youss

+0

Ich persönlich habe mich noch nicht mit den 'timeout' Funktionen angefreundet und so dachte ich, du wärst vielleicht an einem ähnlichen Ort, da du danach fragst. Ist es ein Workaround? So würde ich mich derzeit dem Problem nähern. Wenn Sie mit der Verwendung von 'delay' vertrauter sind, könnte dies eine bessere Lösung sein (unter Berücksichtigung der Wartbarkeit). "outRunningAJob" ist einfach willkürlich, aber selbstdokumentierend. Schön, dass es dir gefallen hat :-) – veeTrain

0

Ich fand das folgende einfacher zu implementieren:

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

Durch die aktuelle Zeichenfolge zu speichern Sie in der Lage sind, um zu sehen, dass der Benutzer die Eingabe beendet wurde. Dann können Sie Ihre Funktion sicher aufrufen, um zu tun, was auch immer verarbeitet werden muss.