20 Stimmen

Wie bringe ich meine jQuery-Live-Suche dazu, eine Sekunde zu warten, bevor die Suche ausgeführt wird?

Ich habe eine Sucheingabe, die Daten von einer Eingabe an eine PHP-Datei sendet, während ich tippe. Die php-Datei führt eine Suche in meiner Datenbank durch und zeigt eine Liste von Suchoptionen an. Sie wissen, die Ajax-Stil Live-Suche.

Mein Problem ist, wenn man etwas sehr schnell eingibt, kann es sein, dass die Suche nur anhand der ersten 1 oder 2 Buchstaben durchgeführt wird, auch wenn noch 10 weitere Buchstaben eingegeben wurden. Das verursacht einige Probleme.

Mein jQuery sieht ein bisschen so aus:

$(document).ready(function(){
  $('#searchMe').keyup(function(){
    lookup(this.value);
  });
});

y

function lookup(searchinput) {

  if(searchinput.length == 0) {
    // Hide the suggestion box.
    $("#suggestions").hide();
  } else {

    $('#loading').fadeIn();

    $.post("/RPCsearch.php", {queryString: ""+searchinput+""}, function(data){
      if(data.length > 0) {
        $("#suggestions").html(data).show();
        $('#loading').fadeOut();
      }
    });
  }
} // lookup

Also bin ich einfach neugierig, wie kann ich es so machen, dass mein Skript wartet, bis ich fertig getippt habe, bevor ich die Funktion ausführe? Meine Logik besagt, dass die Funktion ausgeführt wird, wenn eine Taste 200 Mikrosekunden lang nicht gedrückt wurde, andernfalls wird ein bisschen gewartet.

Wie wird das gemacht?

60voto

Josh Stodola Punkte 79569

Einfach, mit setTimeout . Natürlich soll nur ein Timer gleichzeitig laufen, daher ist es wichtig, dass Sie clearTimeout am Anfang der Funktion...

$(function() {
  var timer;
  $("#searchMe").keyup(function() {
    clearTimeout(timer);
    var ms = 200; // milliseconds
    var val = this.value;
    timer = setTimeout(function() {
      lookup(val);
    }, ms);
  });
});

5voto

Phrogz Punkte 283167

Vielleicht interessieren Sie sich für meine bindDelayed jQuery-Mini-Plugin. Es:

  • Ermöglicht es Ihnen, eine Verzögerung vor dem Start der Anfrage anzugeben
  • Storniert automatisch alle vorhergehenden Anfragen, die für die Auslösung geplant waren
  • Bricht automatisch alle laufenden XHR-Anfragen ab, wenn Sie Ihre Anfrage stellen
  • Ruft Ihren Callback nur für die letzte Anfrage auf
    • Wenn der Benutzer "s" eintippt, lange genug wartet, bis die Anfrage rausgeht, und dann "a" eintippt, und die Antwort für "s" vor der Antwort für "sa" zurückkommt, müssen Sie sich nicht darum kümmern.

Die Antwort auf die ursprüngliche Frage mit bindDelayed würde folgendermaßen aussehen:

// Wait 200ms before sending a request,
// avoiding, cancelling, or ignoring previous requests
$('#searchMe').bindDelayed('keyup',200,'/RPCsearch.php',function(){
  // Construct the data to send with the search each time
  return {queryString:this.value};
},function(html){
  // Use the response, secure in the knowledge that this is the right response
  $("#suggestions").html(html).show();
},'html','post');

Für den Fall, dass meine Seite nicht erreichbar ist, hier der Plugin-Code für die Nachwelt von Stack Overflow:

(function($){
  // Instructions: http://phrogz.net/jquery-bind-delayed-get
  // Copyright:    Gavin Kistner, !@phrogz.net
  // License:      http://phrogz.net/js/_ReuseLicense.txt
  $.fn.bindDelayed = function(event,delay,url,dataCallback,callback,dataType,action){
    var xhr, timer, ct=0;
    return this.on(event,function(){
      clearTimeout(timer);
      if (xhr) xhr.abort();
      timer = setTimeout(function(){
        var id = ++ct;
        xhr = $.ajax({
          type:action||'get',
          url:url,
          data:dataCallback && dataCallback(),
          dataType:dataType||'json',
          success:function(data){
            xhr = null;
            if (id==ct) callback.call(this,data);
          }
        });
      },delay);
    });
  };
})(jQuery);

3voto

tvanfosson Punkte 506878

Sie sollten wirklich die Verwendung der jQuery Autovervollständigen Plugin. Ich finde dieses Plugin sehr nützlich und es tut bereits, was Sie brauchen. Sehen Sie sich besonders die Verzögerung an Option die Sie anpassen können, um zu bestimmen, wie lange das Plugin nach einem Tastendruck wartet, bis es ausgeführt wird.

1voto

Alan Jackson Punkte 6093

1 Lösung in Psuedocode:

OnKeyPress()
    txt = getTxt
    sleep(200)
    newTxt = getTxt
    if (txt == newTxt)  // nothing has been typed so do something
       run my thing

1voto

spence Punkte 1

Dieser ist glücklich

 $(document).ready(function(){

   $("#searchMe").keyup(function () {

  try{window.clearTimeout(timeoutID);}catch(e){}
  timeoutID = window.setTimeout(run, 2000); //delay

  function run()
  {      //dowhatev
    var text = $("#searchMe").val();
    //$("#showit").html(text);       
  }     
 });   
});

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X