javascript jQuery 按键延迟
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14471889/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
jQuery keyup Delay
提问by Tarquin
Hopefully this is a quick and easy one for someone to figure out. I am fairly new to using a lot of javascript/jquery, and I have the following setup to pull a customer name out of a database and display it as the user has finished typing the customer ID.
希望这对某人来说是一个快速而简单的方法。我对使用大量 javascript/jquery 还很陌生,我有以下设置从数据库中提取客户名称并在用户完成输入客户 ID 时显示它。
All works great, but it searches at each keyup. I know I could change it to blurbut I want it to search as they go, at a delay.
一切都很好,但它会搜索每个keyup。我知道我可以将其更改为模糊,但我希望它可以在延迟时进行搜索。
Here is the current code:
这是当前的代码:
function postData(){
var id = $('#id').val();
$.post('inc/repairs/events-backend.php',{id:id},
function(data){
$("#display_customer").html(data);
});
return false;
}
$(function() {
$("#id").bind('keyup',function() {postData()});
});
As you can see it is binding to each keyup which means that if you search too quick, it may leave you with the wrong result as it was still being loaded. (ie if no matches are found, it displays an error, and typing fast enough leaves the user needing to backspace and retype the last number)
正如您所看到的,它绑定到每个 keyup,这意味着如果您搜索得太快,它可能会给您留下错误的结果,因为它仍在加载中。(即,如果未找到匹配项,则会显示错误,并且输入速度足够快让用户需要退格并重新输入最后一个数字)
Could someone assist in adding a delay to the existing code, and if possible a small explaination as to the change you made, I rather not just copy and paste without understanding.
有人可以协助在现有代码中添加延迟,如果可能的话,对您所做的更改做一个小小的解释,我宁愿在不理解的情况下复制和粘贴。
---- EDIT ----
- - 编辑 - -
This is the code I finished up with, thank you guys!
这是我完成的代码,谢谢大家!
function postData(){
var id = $('#id').val();
$.post('inc/repairs/events-backend.php',{id:id},
function(data){
$("#display_customer").html(data);
});
return false;
}
$(function() {
var timer;
$("#id").bind('keyup input',function() {
timer && clearTimeout(timer);
timer = setTimeout(postData, 300);
});
});
采纳答案by Joseph Silber
You should look into the setTimeout
and clearTimeout
functions:
您应该查看setTimeout
和clearTimeout
功能:
$(function() {
var timer;
$("#id").on('keyup',function() {
timer && clearTimeout(timer);
timer = setTimeout(postData, 300);
});
});
Basically what we're doing is that instead of firing the postData
function immediately, we're passing it to setTimeout
, so that it fires after a given amount of time (in this case, 300 milliseconds).
基本上,我们所做的是,不是postData
立即触发函数,而是将其传递给setTimeout
,以便在给定的时间(在本例中为 300 毫秒)后触发。
The setTimeout
function returns a timer ID, which we can then pass to clearTimeout
to cancel that call from ever running. On every keypress, before we set a new timer, we first check if there's a timer set. If there is, we cancel the old timer before starting a new one.
该setTimeout
函数返回一个计时器 ID,然后我们可以传递给它clearTimeout
以取消该调用。在每次按键时,在设置新计时器之前,我们首先检查是否设置了计时器。如果有,我们在开始新的计时器之前取消旧的计时器。
To further enhance this, you can also abort your AJAX callon every keypress, just in case the user typed something after 300+ milliseconds (after the timer fires, but before the AJAX request returned).
为了进一步增强这一点,您还可以在每次按键时中止 AJAX 调用,以防万一用户在 300 多毫秒后(在计时器触发之后,但在 AJAX 请求返回之前)输入内容。
P.S.You should check out Ben Alman's throttle/debounce plugin, which would work perfectly here.
PS你应该看看 Ben Alman 的油门/去抖插件,它在这里工作得很好。
回答by Nevir
Take a look at Underscore's debounce
function- it makes this sort of behavior super straightforward:
看看Underscore 的debounce
函数——它使这种行为变得非常简单:
$(function() {
$('#id').on('keyup input', _.debounce(postData, 500))
}
This way, the call to postData
will only occur after the user has stopped typingfor 500ms
(or whatever you set the debounce wait
to)
通过这种方式,调用postData
用户后只发生已经停止打字的500ms
(或者你设置的防反跳wait
到)
Also, I snuck in the input
eventto catch additional changes like copy/paste in addition to keystrokes (in modern browsers)
此外,除了击键(在现代浏览器中)之外,我还偷偷参加了input
活动以捕获其他更改,例如复制/粘贴
回答by Explosion Pills
I would delay the search a bit on keyup, but you also need to abort the last request since you can't predict what order they will execute (oryou can use a queue for the ajax).
我会在 keyup 上稍微延迟搜索,但是您还需要中止最后一个请求,因为您无法预测它们将执行的顺序(或者您可以使用 ajax 队列)。
I'll describe all three parts:
我将描述所有三个部分:
Delay
延迟
Wrap the postData callback in setTimeout
. Store the return value of setTimeout
as $("#id").data('timeout')
and call clearTimeout
on it each time so that the event fires only once per fast string of characters typed.
将 postData 回调包装在setTimeout
. 存储setTimeout
as的返回值$("#id").data('timeout')
并clearTimeout
每次调用它,以便每个输入的快速字符串仅触发一次事件。
Abort
中止
Store the last request on $("#id").data('lastRequest')
or the like. Each time postData
is called, run $("#id").data('lastRequest').abort()
. Store the return value of $.post()
in that data field. To prevent an error, initialize like this:
存储最后一个请求$("#id").data('lastRequest')
等等。每次postData
被调用,运行$("#id").data('lastRequest').abort()
。将 的返回值存储 $.post()
在该数据字段中。为了防止错误,初始化如下:
$("#id").data('lastRequest', {abort: function () {}));
Queue
队列
$("#id").data('lastRequest', true);
...
$.when($("#id").data('lastRequest')).then(function () {
$("#id").data('lastRequest', $.post(...));
});
回答by pierdevara
There might be a better way but here's something off the top of my head:
可能有更好的方法,但这里有一些让我头疼的事情:
window.currentKeyup = 0;
$("#id").bind('keyup',function() {
window.currentKeyup++;
var keyup = window.currentKeyup;
setTimeout(function(){
if( keyup == window.currentKeyup ){
postData();
}
},3000);
});