我有一个基于网络的搜索输入。在每个onkeyup事件中,从使用JavaScript的客户端到返回搜索响应的PHP文档发出异步请求 - 然后JS获取搜索响应并将其写入客户端。这部分工作正常。
但是,我的问题是用户输入的搜索字词的速度比系统响应的速度快。
假设一个快速输入的用户正在搜索单词super
。用户键入s
(并且s
已完成搜索),正在执行搜索并为s
用户键入u
编写,现在搜索su
排队等候。然后,这个非常快速的输入用户输入p
,而s
的初始搜索结束,现在搜索su
和sup
排队。
如果用户输入速度很慢,则没有问题,我的搜索工具可以响应每个密钥而无需排队搜索请求。但是,如果用户输入速度非常快,他们会在完成键入搜索字词后看到多个搜索结果刷新,因为脚本正在完成队列中的项目。
我如何改进代码以改善用户体验?
例如,您如何编写此脚本以便排除除最后一个项目以外的所有排队项目?
答案 0 :(得分:4)
您可以通过一次超时(称为 debouncing )来执行此操作:
“去抖动意味着将几个暂时接近的信号合并为一个信号。”
var timer;
function keyup() {
clearTimeout(timer);
timer = setTimeout(function() {
search(this.value);
timer = null;
}, timer ? 50 : 1);
}
此代码表示如果用户输入速度过快(在这种情况下delta <50ms),操作将不会排队,但最新的操作总是会覆盖以前的操作。
还有另一种方法(称为 限制 ):
“限制是重复事件发生率的降低。”
var timer;
function keyup() {
if (!timer)
timer = setTimeout(function() {
search(this.value);
timer = null;
}, 100);
}
}
最后,您可以一次获取更多数据以解决延迟问题 请参阅此信息,了解 Flickr 是如何做到的: Building Fast Client-side Searches
还要确保使用某种缓存(APC / memcache),具体取决于数据更改的频率。这可以大大减轻数据库的压力。
答案 1 :(得分:3)
我认为最好的解决方案是“onkeyup”的计时器。
使用jQuery的示例:
var timer = null;
$('input').keyup(function(){
if(timer!=null){
clearTimeout(timer);
}
// wait and call in 150 ms
timer = setTimeout(function() {
// call here your search function!
....
}, 150);
});
答案 2 :(得分:0)
正如一些人所提到的,您可以使用超时来减慢从服务器获取结果的速度。但请注意,这仍然会为用户显示一个小延迟。
如果数据是在页面加载时被提取和存储的候选者,那么只需从客户端内存中检索它就可以提供更快的自动完成解决方案。