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

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

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

我该怎么做呢?


当前回答

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

其他回答

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

我很惊讶,没有人提到多重输入的问题在CMS的非常好的剪辑。

基本上,你必须为每个输入分别定义延迟变量。否则,如果有人把文本放在第一个输入,并迅速跳转到其他输入并开始输入,第一个的回调将不会被调用!

下面是我根据其他答案编写的代码:

(function($) {
    /**
     * KeyUp with delay event setup
     * 
     * @link http://stackoverflow.com/questions/1909441/jquery-keyup-delay#answer-12581187
     * @param function callback
     * @param int ms
     */
    $.fn.delayKeyup = function(callback, ms){
            $(this).keyup(function( event ){
                var srcEl = event.currentTarget;
                if( srcEl.delayTimer )
                    clearTimeout (srcEl.delayTimer );
                srcEl.delayTimer = setTimeout(function(){ callback( $(srcEl) ); }, ms);
            });

        return $(this);
    };
})(jQuery);

该解决方案将setTimeout引用保留在输入的delayTimer变量中。它还像fazzyx建议的那样将元素的引用传递给回调。

在IE6, 8(comp - 7), 8和Opera 12.11中测试。

CMS的回答又有了一点改进。为了方便地允许单独的延迟,您可以使用以下方法:

function makeDelay(ms) {
    var timer = 0;
    return function(callback){
        clearTimeout (timer);
        timer = setTimeout(callback, ms);
    };
};

如果你想重复使用相同的延迟,就这样做

var delay = makeDelay(250);
$(selector1).on('keyup', function() {delay(someCallback);});
$(selector2).on('keyup', function() {delay(someCallback);});

如果你想分开延迟,可以这样做

$(selector1).on('keyup', function() {makeDelay(250)(someCallback);});
$(selector2).on('keyup', function() {makeDelay(250)(someCallback);});

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

这个函数获取输入字段的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);
});

好吧,我也做了一段代码限制高频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 */ });
});