希望这对于某人来说是一个快速而简单的方法。我使用大量的javascript / jquery是相当新的,我有以下设置从数据库中提取客户名称并在用户输入客户ID时显示它。
一切都很棒,但它会搜索每个 keyup 。我知道我可以将其更改为 blur ,但我希望它能够在延迟时进行搜索。
以下是当前代码:
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()});
});
正如您所看到的那样,它绑定到每个keyup,这意味着如果搜索速度太快,可能会因为它仍然被加载而导致错误的结果。 (即如果没有找到匹配项,则会显示错误,并且键入足够快的速度会使用户需要退格并重新键入最后一个数字)
有人可以协助为现有代码添加延迟,如果可能的话,对您所做的更改进行一次小的解释,我不仅仅是在不理解的情况下进行复制和粘贴。
----编辑----
这是我完成的代码,谢谢你们!
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);
});
});
答案 0 :(得分:8)
您应该查看setTimeout
和clearTimeout
函数:
$(function() {
var timer;
$("#id").on('keyup',function() {
timer && clearTimeout(timer);
timer = setTimeout(postData, 300);
});
});
基本上我们正在做的是,不是立即触发postData
函数,而是将它传递给setTimeout
,以便在给定的时间后触发它(在这种情况下, 300毫秒)。
setTimeout
函数返回一个计时器ID,我们可以将其传递给clearTimeout
以取消该运行的呼叫。在每次按键时,在我们设置新计时器之前,我们首先检查是否设置了计时器。如果有,我们在开始新计时之前取消旧计时器。
为了进一步增强这一点,您还可以在每个按键上abort your AJAX call,以防万一用户在300+毫秒后输入内容(在计时器触发后,但在返回AJAX请求之前)。
P.S。你应该查看Ben Alman的throttle/debounce plugin,这在这里可以很好地运作。
答案 1 :(得分:7)
看看Underscore's debounce
function - 它使这种行为变得非常简单:
$(function() {
$('#id').on('keyup input', _.debounce(postData, 500))
}
这样,只有在用户停止输入 postData
(或您设置的去抖动500ms
之后)之后才会调用wait
另外,我偷偷进入the input
event以捕获除了击键之外的其他更改,例如复制/粘贴(在现代浏览器中)
答案 2 :(得分:2)
我会在keyup上延迟搜索,但你还需要中止最后一个请求,因为你无法预测它们将执行的顺序(或你可以使用ajax的队列)。
我将描述所有三个部分:
在setTimeout
中包装postData回调。将setTimeout
的返回值存储为$("#id").data('timeout')
并每次调用clearTimeout
,以便每个快速输入的字符串只触发一次事件。
将最后一个请求存储在$("#id").data('lastRequest')
之类。每次调用postData
时,请运行$("#id").data('lastRequest').abort()
。将$.post()
的返回值存储在该数据字段中。要防止出错,请按以下方式初始化:
$("#id").data('lastRequest', {abort: function () {}));
$("#id").data('lastRequest', true);
...
$.when($("#id").data('lastRequest')).then(function () {
$("#id").data('lastRequest', $.post(...));
});
答案 3 :(得分:0)
可能有更好的方法,但这里有一些不可思议的东西:
window.currentKeyup = 0;
$("#id").bind('keyup',function() {
window.currentKeyup++;
var keyup = window.currentKeyup;
setTimeout(function(){
if( keyup == window.currentKeyup ){
postData();
}
},3000);
});