我有一个div列表,它们在文本输入框中有各种数据。
我有一个工作" Live Search"其中,当用户在input
框中键入信息时,会对div进行过滤,直到只显示匹配的或完全没有。
但是,当行数很多时,响应速度变慢,搜索条件的输入速度很慢。
是否有更快或更有效的方法?
代码
$('input#create-row-name').keyup(function(e){
if($(this).val()!==''){
liveSearch();
} else $('div#rows>div.column>div.row').show();
});
function liveSearch(){
var searchTerm = $('input#create-row-name').val().toString().toLowerCase();
$('div#rows>div.column>div.row').each(function(){
var searchResult = $(this).find('div.input-group>input.row-name').val().toString().toLowerCase();
if(searchResult.indexOf(searchTerm)>=0){
$(this).show();
} else $(this).hide();
})
}
答案 0 :(得分:4)
缓存值。删除关键部分中的jQuery。
var $rows = $('div#rows>div.column>div.row');
var texts = $rows.map(function () {
return $(this).find("div.input-group > input.row-name").text().toLowerCase();
}).toArray();
$('input#create-row-name').on("keyup paste drop", function () {
var searchTerm = $.trim( this.value.toLowerCase() ),
lastTerm = $(this).data("lastTerm"),
i, found;
if (searchTerm === lastTerm) return;
$(this).data("lastTerm", searchTerm);
for (i = texts.length - 1; i >= 0; i--) {
found = searchTerm === '' || texts[i].indexOf(searchTerm) > -1;
$rows[i].style.display = found ? "" : "none";
}
});
绝对明智的做法是让搜索等到用户完成输入后,而不是在每个keyup事件后立即运行。我推荐debounce function like the one Sugar.js provides。
另外(作为一般提示,由于缓存而在此处不那么相关):请记住,过度特定的选择器效率较低。 div#rows > div.column > div.row
在计算上比 - { - 1}}更贵 - 但可能相当于 - #rows .row
。
答案 1 :(得分:2)
不是在每一次按键上都经过列表,而是在那里稍微延迟,这样如果有人快速连续输入多个字符,那么每次都不会这样做。 (这是几年前有人告诉我的一个技巧。)
所以,例如,像这样的东西(未经测试)......
var keyupTimer = -1;
$('input#create-row-name').keyup(function(e){
if ($(this).val()!==''){
if(keyupTimer != -1)
window.clearTimeout(keyupTimer);
keyupTimer = window.setTimeout(function(){
liveSearch();
keyupTimer = -1;
},200);
} else $('div#rows>div.column>div.row').show();
});
这将在1/5秒后运行liveSearch
,足以允许普通打字员在代码完成其工作之前按几个键。
更新
正如@Halcyon评论的那样,如果计时器中运行的代码已经优化了,那么上面就好了......正如他所指出的那样,你的代码不是。
我会建议您先使用@Tomalak和@Halcyon提供的答案,而不是尝试写新内容......如果您仍然需要改进,请尝试使用我的建议。
答案 2 :(得分:1)
jQuery查找非常慢。看看你是否可以优化它们。您可以构建如下索引:
(function () {
var index = new WeakMap();
$('input#create-row-name').keyup(function(e){
if($(this).val()!==''){
liveSearch();
} else $('div#rows>div.column>div.row').show();
});
// build index once initially
$('div#rows>div.column>div.row').each(function(i, o){
index.set(o, $(this).find('div.input-group>input.row-name'));
// maybe even cache `.val().toString().toLowerCase()`?
})
function liveSearch(){
var searchTerm = $('input#create-row-name').val().toString().toLowerCase();
$('div#rows>div.column>div.row').each(function(i, o){
// use index here
var searchResult = index.get(o).val().toString().toLowerCase();
if(searchResult.indexOf(searchTerm)>=0){
$(this).show();
} else $(this).hide();
})
}
}());
这可以显着加快您的代码速度。
答案 3 :(得分:0)
只进行基于JQuery的小改动,这就是我所得到的。
$('input#create-row-name').keyup(function(e){
var text=$(this).val().toString().toLowerCase();
if(text!==''){
liveSearch(text);
} else $('div#rows>div.column>div.row').show();
});
function liveSearch(searchTerm){
$('#rows input.row-name').each(function(){
var searchResult = $(this).val().toString().toLowerCase();
var $divHide=$(this).closest("div.row");
if(searchResult.indexOf(searchTerm)>=0){
$divHide.show();
} else $divHide.hide();
})
}
我所做的改动是
其他更好的答案出现了,因为我正在输入这个,我建议他们超过我的。我只是想提交我的解决方案。