使用JavaScript快速筛选记录列表
我在一个网页上有一个大约10000名客户的列表,需要能够在此列表中搜索匹配的输入。它会有一些延迟,我正在寻找提高性能的方法。下面是我使用的HTML和JavaScript的简化示例:使用JavaScript快速筛选记录列表,javascript,jquery,html,dom,Javascript,Jquery,Html,Dom,我在一个网页上有一个大约10000名客户的列表,需要能够在此列表中搜索匹配的输入。它会有一些延迟,我正在寻找提高性能的方法。下面是我使用的HTML和JavaScript的简化示例: <input id="filter" type="text" /> <input id="search" type="button" value="Search" /> <div id="customers"> <div class='customer-wrapper
<input id="filter" type="text" />
<input id="search" type="button" value="Search" />
<div id="customers">
<div class='customer-wrapper'>
<div class='customer-info'>
...
</div>
</div>
...
</div>
<script type="text/javascript">
$(document).ready(function() {
$("#search").on("click", function() {
var filter = $("#filter").val().trim().toLowerCase();
FilterCustomers(filter);
});
});
function FilterCustomers(filter) {
if (filter == "") {
$(".customer-wrapper").show();
return;
}
$(".customer-info").each(function() {
if ($(this).html().toLowerCase().indexOf(filter) >= 0) {
$(this).parent().show();
} else {
$(this).parent().hide();
}
});
}
</script>
...
...
$(文档).ready(函数(){
$(“#搜索”)。在(“单击”,函数()上){
var filter=$(“#filter”).val().trim().toLowerCase();
过滤器客户(过滤器);
});
});
功能过滤器客户(过滤器){
如果(过滤器==“”){
$(“.customer wrapper”).show();
返回;
}
$(“.customer info”)。每个(函数(){
if($(this.html().toLowerCase().indexOf(filter)>=0){
$(this.parent().show();
}否则{
$(this.parent().hide();
}
});
}
问题是,当我点击搜索按钮时,有一个相当长的延迟,直到我得到匹配结果的列表。有没有更好的方法来过滤列表?问题是,您正在迭代记录,拥有10000条记录可能会非常慢,因此我的建议是稍微更改结构,这样您就不必迭代:
customer wrapper
类并使其成为所有列表元素的父div下划线\u name
var customerHtml=“+name+”代码>
列表中的每个元素都有一个唯一的id,该id将与名称“几乎”相同,并且列表中的所有元素都将位于customer wrapper
类下的同一级别
对于搜索,您可以使用用户输入替换下划线的空格,并将其放入变量中,例如searchable\u id
,并使用Jquery:
$(“#”+可搜索的_id).兄弟姐妹().hide()
同级
将隐藏与可搜索\u id相同级别上的其他元素
它可能存在的唯一问题是,如果出现两个或多个重复名称的情况,因为它将尝试创建两个或多个具有相同id的div
您可以在上检查一个简单的实现
多亏了您的回答和评论,我至少找到了性能令人满意的解决方案。我已经清理了多余的包装,并在列表中分组显示/隐藏元素,而不是对每个元素单独进行。下面是过滤现在的样子:
function FilterCustomers(filter) {
if (filter == "") {
$(".customer-info").show();
} else {
$(".customer-info").hide();
$(".customer-info").removeClass("visible");
$(".customer-info").each(function() {
if ($(this).html().toLowerCase().indexOf(filter) >= 0) {
$(this).addClass("visible");
}
});
$(".customer-info.visible").show();
}
}
一个测试示例1)DOM操作通常很慢,尤其是在添加新元素时。将所有html放入一个变量并附加它,这将导致一个DOM操作,并且比为每个元素执行DOM操作要快得多
function LoadCustomers() {
var count = 10000;
var customerHtml = "";
for (var i = 0; i < count; i++) {
var name = GetRandomName() + " " + GetRandomName();
customerHtml += "<div class='customer-info'>" + name + "</div>";
}
$("#customers").append(customerHtml);
}
示例:我建议您将此问题转移到GetRandomName
之外的LoadCustomers()
中,并且只进行一次循环调用(更改返回以满足您的需要)将有所改进。。。ut codereview是您的位置!谢谢你们的评论,我以前不知道代码审查。我从问题中删除了LoadCustomers()的测试示例,因为根本不存在问题。列表更新缓慢,这就是FilterCustomers(filter)功能。瓶颈是那些.show()
和.hide()
东西。从循环中删除它们:收集迭代中的项目,并将它们放入两个bucket/列表中,一旦完成show
show
bucket中的项目,然后hide
其余的项目。为什么您一次需要在DOM中输入10000个名称?这是用户的信息过载,渲染速度慢。改为过滤数据,然后更新DOM谢谢您的建议!首先,消除要过滤的对象周围的冗余HTML非常好。其他的则不适合,因为过滤器应该适用于许多匹配项。此外,为对象提供客户名称是个坏主意,因为它们包含许多Unicode符号(它们不全是英语),但是客户有数字ID,如果有帮助的话,可以使用数字ID。
function FilterCustomers(filter) {
var customers = $('.customer-info').get();
var length = customers.length;
var customer = null;
var i = 0;
var applyFilter = false;
if (filter.length > 0) {
applyFilter = true;
}
for (i; i < length; i++) {
customer = customers[i];
if (applyFilter && customer.innerHTML.toLowerCase().indexOf(filter) < 0) {
$(customer).addClass('hidden');
} else {
$(customer).removeClass('hidden');
}
}
}