我有一个搜索域。现在它会搜索每一个按键。所以如果有人输入“Windows”,它会用AJAX搜索每个键:“W”,“Wi”,“Win”,“Wind”,“Windo”,“Window”,“Windows”。
我想有一个延迟,所以它只在用户停止输入200毫秒时搜索。
在keyup函数中没有这个选项,我尝试了setTimeout,但它不起作用。
我该怎么做呢?
我有一个搜索域。现在它会搜索每一个按键。所以如果有人输入“Windows”,它会用AJAX搜索每个键:“W”,“Wi”,“Win”,“Wind”,“Windo”,“Window”,“Windows”。
我想有一个延迟,所以它只在用户停止输入200毫秒时搜索。
在keyup函数中没有这个选项,我尝试了setTimeout,但它不起作用。
我该怎么做呢?
当前回答
根据CMS的回答,我做出了这样的决定:
把下面的代码包括jQuery后:
/*
* delayKeyup
* http://code.azerti.net/javascript/jquery/delaykeyup.htm
* Inspired by CMS in this post : http://stackoverflow.com/questions/1909441/jquery-keyup-delay
* Written by Gaten
* Exemple : $("#input").delayKeyup(function(){ alert("5 secondes passed from the last event keyup."); }, 5000);
*/
(function ($) {
$.fn.delayKeyup = function(callback, ms){
var timer = 0;
$(this).keyup(function(){
clearTimeout (timer);
timer = setTimeout(callback, ms);
});
return $(this);
};
})(jQuery);
简单地像这样使用:
$('#input').delayKeyup(function(){ alert("5 secondes passed from the last event keyup."); }, 5000);
注意:作为参数传递的函数中的$(this)变量与输入不匹配
其他回答
根据CMS的回答,我做出了这样的决定:
把下面的代码包括jQuery后:
/*
* delayKeyup
* http://code.azerti.net/javascript/jquery/delaykeyup.htm
* Inspired by CMS in this post : http://stackoverflow.com/questions/1909441/jquery-keyup-delay
* Written by Gaten
* Exemple : $("#input").delayKeyup(function(){ alert("5 secondes passed from the last event keyup."); }, 5000);
*/
(function ($) {
$.fn.delayKeyup = function(callback, ms){
var timer = 0;
$(this).keyup(function(){
clearTimeout (timer);
timer = setTimeout(callback, ms);
});
return $(this);
};
})(jQuery);
简单地像这样使用:
$('#input').delayKeyup(function(){ alert("5 secondes passed from the last event keyup."); }, 5000);
注意:作为参数传递的函数中的$(this)变量与输入不匹配
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);});
我使用这个小函数也是出于同样的目的,在用户停止输入一段特定的时间后,或者在以高速率触发的事件中执行一个函数,比如resize:
function delay(callback, ms) { var timer = 0; return function() { var context = this, args = arguments; clearTimeout(timer); timer = setTimeout(function () { callback.apply(context, args); }, ms || 0); }; } // Example usage: $('#input').keyup(delay(function (e) { console.log('Time elapsed!', this.value); }, 500)); <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <label for="input">Try it: <input id="input" type="text" placeholder="Type something here..."/> </label>
工作原理:
delay函数将返回一个内部处理单个计时器的包装函数,在每次执行时,计时器都会根据所提供的时间延迟重新启动,如果在此时间之前发生多次执行,计时器将重置并重新启动。
当计时器最终结束时,执行回调函数,传递原始上下文和参数(在本例中,是jQuery的事件对象和DOM元素)。
更新2019-05-16
我在现代环境中使用ES5和ES6特性重新实现了该功能:
function delay(fn, ms) {
let timer = 0
return function(...args) {
clearTimeout(timer)
timer = setTimeout(fn.bind(this, ...args), ms || 0)
}
}
该实现包含一组测试。
对于更复杂的东西,看看jQuery Typewatch插件。
下面是我写的一个建议,它可以处理表单中的多个输入。
这个函数获取输入字段的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 */ });
});