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

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

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

我该怎么做呢?


当前回答

你也可以看看underscore.js,它提供了像debounce这样的实用方法:

var lazyLayout = _.debounce(calculateLayout, 300);
$(window).resize(lazyLayout);

其他回答

如果你想在一段时间后做一些事情,并在特定的事件(如keyup)后重置定时器,最好的解决方案是使用clearTimeout和setTimeout方法:

// declare the timeout variable out of the event listener or in the global scope
var timeout = null;

$(".some-class-or-selector-to-bind-event").keyup(function() {
    clearTimeout(timout); // this will clear the recursive unneccessary calls
    timeout = setTimeout(() => {
         // do something: send an ajax or call a function here
    }, 2000);
    // wait two seconds

});

Use

mytimeout = setTimeout( expression, timeout );

其中expression是要运行的脚本,timeout是在它运行之前等待的时间(以毫秒为单位)——这不会暂停脚本,而是简单地延迟该部分的执行,直到超时完成。

clearTimeout(mytimeout);

将重置/清除超时,这样它就不会在表达式中运行脚本(就像取消),只要它还没有被执行。

在CMS的回答的基础上,这里有一个新的延迟方法,它保留了“this”的用法:

var delay = (function(){
  var timer = 0;
  return function(callback, ms, that){
    clearTimeout (timer);
    timer = setTimeout(callback.bind(that), ms);
  };
})();

用法:

$('input').keyup(function() {
    delay(function(){
      alert('Time elapsed!');
    }, 1000, this);
});

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

使用jQuery插件bindWithDelay:

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