我有一个搜索域。现在它会搜索每一个按键。所以如果有人输入“Windows”,它会用AJAX搜索每个键:“W”,“Wi”,“Win”,“Wind”,“Windo”,“Window”,“Windows”。

我想有一个延迟,所以它只在用户停止输入200毫秒时搜索。

在keyup函数中没有这个选项,我尝试了setTimeout,但它不起作用。

我该怎么做呢?


当前回答

在ES6中,也可以使用箭头函数语法。

在本例中,在调用searchFunc发出查询请求之前,在用户完成输入之后,代码将keyup事件延迟400ms。

const searchbar = document.getElementById('searchBar');
const searchFunc = // any function

// wait ms (milliseconds) after user stops typing to execute func
const delayKeyUp = (() => {
    let timer = null;
    const delay = (func, ms) => {
        timer ? clearTimeout(timer): null
        timer = setTimeout(func, ms)
    }
    return delay
})();

searchbar.addEventListener('keyup', (e) => {
    const query = e.target.value;
    delayKeyUp(() => {searchFunc(query)}, 400);
})

更新后的Typescript版本:

const delayKeyUp = (() => {
  let timer: NodeJS.Timeout;
  return (func: Function, ms: number) => {
    timer ? clearTimeout(timer) : null;
    timer = setTimeout(() => func(), ms);
  };
})();

其他回答

好吧,我也做了一段代码限制高频ajax请求由Keyup / Keydown。看看这个:

https://github.com/raincious/jQueue

像这样提问:

var q = new jQueue(function(type, name, callback) {
    return $.post("/api/account/user_existed/", {Method: type, Value: name}).done(callback);
}, 'Flush', 1500); // Make sure use Flush mode.

并像这样绑定事件:

$('#field-username').keyup(function() {
    q.run('Username', this.val(), function() { /* calling back */ });
});

看一下autocomplete插件。我知道它允许您指定延迟或最小字符数。即使你最终没有使用这个插件,浏览代码也会给你一些关于如何自己实现它的想法。

如果你想在类型完成后搜索,使用一个全局变量来保存setTimout调用返回的超时,如果它还没有发生,就用clearTimeout取消它,这样它就不会触发超时,除非在最后一个keyup事件

var globalTimeout = null;  
$('#id').keyup(function(){
  if(globalTimeout != null) clearTimeout(globalTimeout);  
  globalTimeout =setTimeout(SearchFunc,200);  
}   
function SearchFunc(){  
  globalTimeout = null;  
  //ajax code
}

或者使用匿名函数:

var globalTimeout = null;  
$('#id').keyup(function() {
  if (globalTimeout != null) {
    clearTimeout(globalTimeout);
  }
  globalTimeout = setTimeout(function() {
    globalTimeout = null;  

    //ajax code

  }, 200);  
}   

下面是我写的一个建议,它可以处理表单中的多个输入。

这个函数获取输入字段的Object,放到你的代码中

function fieldKeyup(obj){
    //  what you want this to do

} // fieldKeyup

这是实际的delayCall函数,负责多个输入字段

function delayCall(obj,ms,fn){
    return $(obj).each(function(){
    if ( typeof this.timer == 'undefined' ) {
       // Define an array to keep track of all fields needed delays
       // This is in order to make this a multiple delay handling     
          function
        this.timer = new Array();
    }
    var obj = this;
    if (this.timer[obj.id]){
        clearTimeout(this.timer[obj.id]);
        delete(this.timer[obj.id]);
    }

    this.timer[obj.id] = setTimeout(function(){
        fn(obj);}, ms);
    });
}; // delayCall

用法:

$("#username").on("keyup",function(){
    delayCall($(this),500,fieldKeyup);
});

使用jQuery插件bindWithDelay:

element.bindWithDelay(eventType, [ eventData ], handler(eventObject), timeout, throttle)