在执行搜索之前,如何使我的实时jQuery搜索等待一秒钟?

时间:2009-07-23 13:08:52

标签: javascript jquery ajax

我有一个搜索输入,当我输入时,它会将数据从输入发送到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

所以我只是好奇,我怎么能这样做以便我的脚本等到我在完成打字之后再运行该功能?我的逻辑说的是,如果一个键没有被按下200微秒,运行该功能,否则稍微保持一点。

这是怎么做到的?

6 个答案:

答案 0 :(得分:50)

很简单,使用setTimeout。当然你只需要一个计时器,所以在函数开头使用clearTimeout很重要...

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

答案 1 :(得分:4)

您可能对我的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');

如果我的网站关闭,这里是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);

答案 2 :(得分:3)

你真的应该考虑使用jQuery autocomplete插件。我发现这个插件非常有用,它已经完成了你所需要的。特别注意延迟option,您可以自定义延迟以更改插件运行后插件等待的时间。

答案 3 :(得分:1)

<伪代码中的p1解决方案:

答案 4 :(得分:1)

这个很开心

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

答案 5 :(得分:-1)

将事件附加到keypress,keydown和keyup输入时,我发现了最好的成功。 Safari / FireFox / IE似乎都处理特殊的按键(删除,退格等),但是一起使用所有事件似乎都可以覆盖它。运行所有事件的唯一方法是使用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);
});