我有一个搜索域。现在它会搜索每一个按键。所以如果有人输入“Windows”,它会用AJAX搜索每个键:“W”,“Wi”,“Win”,“Wind”,“Windo”,“Window”,“Windows”。
我想有一个延迟,所以它只在用户停止输入200毫秒时搜索。
在keyup函数中没有这个选项,我尝试了setTimeout,但它不起作用。
我该怎么做呢?
我有一个搜索域。现在它会搜索每一个按键。所以如果有人输入“Windows”,它会用AJAX搜索每个键:“W”,“Wi”,“Win”,“Wind”,“Windo”,“Window”,“Windows”。
我想有一个延迟,所以它只在用户停止输入200毫秒时搜索。
在keyup函数中没有这个选项,我尝试了setTimeout,但它不起作用。
我该怎么做呢?
当前回答
Use
mytimeout = setTimeout( expression, timeout );
其中expression是要运行的脚本,timeout是在它运行之前等待的时间(以毫秒为单位)——这不会暂停脚本,而是简单地延迟该部分的执行,直到超时完成。
clearTimeout(mytimeout);
将重置/清除超时,这样它就不会在表达式中运行脚本(就像取消),只要它还没有被执行。
其他回答
我使用这个小函数也是出于同样的目的,在用户停止输入一段特定的时间后,或者在以高速率触发的事件中执行一个函数,比如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);
});
将CMS的答案与Miguel的答案相结合,产生了允许并发延迟的健壮解决方案。
var delay = (function(){
var timers = {};
return function (callback, ms, label) {
label = label || 'defaultTimer';
clearTimeout(timers[label] || 0);
timers[label] = setTimeout(callback, ms);
};
})();
当您需要单独延迟不同的操作时,请使用第三个参数。
$('input.group1').keyup(function() {
delay(function(){
alert('Time elapsed!');
}, 1000, 'firstAction');
});
$('input.group2').keyup(function() {
delay(function(){
alert('Time elapsed!');
}, 1000, '2ndAction');
});
如果你想在一段时间后做一些事情,并在特定的事件(如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
});
使用标签延迟多函数调用
这是我的解决方案。它会延迟你想要的任何函数的执行。它可以是按下键搜索查询,也可以是快速单击上一个或下一个按钮(否则如果连续快速单击将发送多个请求,并且最终不会使用)。它使用一个全局对象存储每次执行时间,并将其与最新的请求进行比较。
因此,结果是只有最后一个点击/动作将被实际调用,因为这些请求存储在队列中,如果队列中没有其他具有相同标签的请求,则在X毫秒后调用!
function delay_method(label,callback,time){
if(typeof window.delayed_methods=="undefined"){window.delayed_methods={};}
delayed_methods[label]=Date.now();
var t=delayed_methods[label];
setTimeout(function(){ if(delayed_methods[label]!=t){return;}else{ delayed_methods[label]=""; callback();}}, time||500);
}
您可以设置自己的延迟时间(可选,默认为500ms)。并以“闭包方式”发送函数参数。
例如,如果你想调用下面的函数:
function send_ajax(id){console.log(id);}
为了防止多个send_ajax请求,可以使用以下方法延迟它们:
Delay_method ("check date", function(){send_ajax(2);}, 600);
每个使用标签“check date”的请求只有在600毫秒的时间范围内没有其他请求时才会被触发。这个参数是可选的
标签独立性(调用相同的目标函数),但同时运行:
delay_method("check date parallel", function(){send_ajax(2);});
delay_method("check date", function(){send_ajax(2);});
导致调用相同的函数,但由于它们的标签不同而单独延迟它们