Подтвердить что ты не робот

Как сделать мой live jQuery-поиск ждать секунды, прежде чем выполнять поиск?

У меня есть вход для поиска, который отправляет данные из ввода в php файл по мере ввода. Файл php выполняет поиск в моей базе данных и отображает список параметров поиска. Вы знаете, живой стиль в стиле ajax.

Моя проблема в том, что если вы наберете что-то действительно быстрое, оно может просто провести поиск с первых 1 или 2 букв, даже если набрано еще 10. Это вызывает несколько проблем.

Мой jQuery выглядит примерно так:

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

и

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

Итак, мне просто интересно, как я могу сделать это так, чтобы мой script ждал, пока я не закончил печатать до запуска функции? В моей логике говорится, что, если ключ не был нажат на 200 микросекунд, запустите функцию, иначе немного задержитесь.

Как это делается?

4b9b3361

Ответ 1

Просто, используя setTimeout. Конечно, вы хотите, чтобы сразу один таймер заходил, поэтому важно использовать clearTimeout в начале функции...

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

Ответ 2

Вам может быть интересен мой bindDelayed мини-плагин jQuery. Это:

  • Позволяет указать задержку перед началом запроса
  • Автоматически отменяет любые предыдущие запросы, которые должны были быть отправлены
  • Автоматически отменяет любые входящие в эфир запросы XHR, которые выполнялись, когда вы делаете свой запрос
  • Только вызов вашего обратного вызова для последнего запроса
    • Если пользователь набирает "s", ждет достаточно долго, чтобы запрос вышел, а затем набирает "a", а ответ "s" возвращается до ответа "sa", вам не придется справиться с этим.

Ответ на исходный вопрос с помощью bindDelayed будет выглядеть так:

// 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');

В случае, если мой сайт не работает, здесь приведен код плагина для потомков:

(function($){
  // Instructions: http://phrogz.net/jquery-bind-delayed-get
  // Copyright:    Gavin Kistner, [email protected]
  // 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);

Ответ 3

Вам действительно стоит взглянуть на использование плагина jQuery autocomplete. Я считаю, что этот плагин очень полезен, и он уже делает то, что вам нужно. Посмотрите, в частности, на задержку option, которую вы можете настроить, чтобы изменить время ожидания плагина после нажатия клавиши.

Ответ 4

1 решение в psuedocode:

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

Ответ 5

этот счастлив

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

Ответ 6

Я нашел лучший успех при подключении события к нажатиям клавиш, вводам клавиш и вводам ключей. Safari/FireFox/IE, похоже, обрабатывают специальные нажатия клавиш (delete, backspace и т.д.) Немного по-другому, но использование всех событий вместе, похоже, покрывает его. Единственный способ, с помощью которого выполняются все события, - это использовать setTimeout, чтобы при каждом запуске он просто сбрасывал таймер, и в конечном итоге обратный вызов запускается только один раз.

var delay = 200;
var search_timer = null;
$("#searchMe").keydown(function(e) {
    if(search_timer) {
        clearTimeout(search_timer);
    }
    search_timer = setTimeout(lookup, delay);
});
$("#searchMe").keypress(function(e) {
    if(search_timer) {
        clearTimeout(search_timer);
    }
    search_timer = setTimeout(lookup, delay);
});
$("#searchMe").keyup(function(e) {
    if(search_timer) {
        clearTimeout(search_timer);
    }
    search_timer = setTimeout(lookup, delay);
});