这是我用来排序无序的元素列表并根据用户的查询删除它们的jQuery / Javascript代码:
// event binding for the search filter
$('.search-box').keyup(function(){
var query = $(this).val().toLowerCase(),
length = query.length;
$('.friends-list li').each(function(){
if(query.length > 1 && $(this).find('span').text().toLowerCase().substring(0, length) != query){
$(this).hide();
} else {
$(this).show();
}
});
});
不幸的是,当我获得大量的li元素时,这会大大减慢并且有时会挂起系统。有没有办法优化这个,或者先进行所有搜索,然后一次性删除所有li元素,这样系统就不会挂起?
当我进行服务器端搜索时,我可以只有一个加载微调器和一个成功回调,但这似乎不适用于客户端。
答案 0 :(得分:4)
一些提示
不要在每个keyup事件上触发搜索。相反,有一个等待下一个密钥的短计时器(~200ms)并开始搜索是否没有:
keyup:
clearTimeout(searchTimer)
searchTimer = setTimeout(doSearch, 200)
如果query.length <=1
您的循环可以被优化掉,则无需在每次迭代时检查它。
each(li)...find(span)
开销太大了。尝试直接迭代直通:
$('.friends-list li span').each(function() {
var p = $(this);
if(p.text().toLowerCase().indexOf(query) !== 0) {
p.parent().hide();
} else {
p.show();
}
});
另请注意上述代码中的一些小优化。
答案 1 :(得分:3)
我还建议使用for循环,因为它是significantly faster。
答案 2 :(得分:2)
延迟DOM更新是加速此类代码的有效方法。最后完成所有操作,而不是在.each()循环中。
答案 3 :(得分:2)
我建议延迟按键,这样你就不会进行搜索,直到用户停止输入一段时间 - 比如半秒钟,尽管你可以尝试一下并调整它的味道。另外,我对您的搜索进行了一些小的更改,例如,如果您知道搜索字符串太短,您只想显示所有内容,因此在这种情况下无需在循环中测试每个项目。
(function() {
var timerID = null;
function doSearch(query) {
var length = query.length;
if (length <= 1) {
$('.friends-list li').show();
} else {
$('.friends-list li').each(function(){
var $this = $(this);
if($this.find('span').text().toLowerCase()
.substring(0, length) != query)
$this.hide();
else
$this.show();
});
}
}
$('.search-box').keyup(function(){
var searchString = this.value.toLowerCase();
if (timerID)
clearTimeout(timerID);
timerID = setTimeout(function() {
timerID = null;
doSearch(searchString);
}, 500);
});
)();
答案 4 :(得分:0)
目前,您在每次击键时都会进行全面搜索。您可能希望等待一小段时间。说0秒,然后检查是否按下了另一个键。小延迟对于用户体验应该是可以的,甚至几乎不会引起注意,但是如果有人在输入一个单词(快速连续按键),这可以为您节省许多迭代,从而提高经验速度。
答案 5 :(得分:0)
我知道这是旧的,但考虑更好的选择器,缓存元素和事件冒泡(这里不适用) - 搜索优化jQuery,你会得到一堆很棒的技巧。