我在网页上有一个包含大约10 000名客户的列表,并且需要能够在此列表中搜索匹配的输入。它有一些延迟,我正在寻找如何提高性能的方法。以下是我使用的HTML和JavaScript的简化示例:
<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>
问题是,当我点击“搜索”按钮时,会有很长的延迟,直到我得到匹配结果的列表。有没有更好的方法来过滤列表?
答案 0 :(得分:3)
1) DOM操作通常很慢,尤其是当您添加新元素时。将所有html放入变量并追加它,这会产生一个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);
}
2) jQuery.each()很慢,请改用for
循环
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');
}
}
}
答案 1 :(得分:1)
感谢您的所有答案和评论,我至少能够获得满意的绩效结果。我已经清理了多余的包装器,并在列表中对元素进行了分组显示/隐藏,而不是为每个元素单独执行。以下是过滤的内容:
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();
}
}
答案 2 :(得分:0)
问题是你正在迭代记录,而拥有10000它可能非常慢,所以我的建议是稍微改变结构,所以你不必迭代:
在customer-wrapper
上定义列表的所有css功能
类并将其设为所有列表元素的父div 。
当您的ajax请求添加元素时,创建一个包含替换下划线空格的名称的变量,让我们将其称为underscore_name
。
将名称添加到列表中:
var customerHtml = "<div id='"+underscore_name+'>" + name + "</div>";
列表中的每个元素都有一个唯一的ID,几乎就是&#34;与名称相同,列表的所有元素都位于customer-wrapper
类下的相同级别。
searchable_id
,并使用Jquery: $('#'+searchable_id).siblings().hide()
;
siblings
会隐藏与 searchable_id 相同级别的其他元素。
唯一的问题是,如果有两个或更多重复名称的情况,因为它会尝试创建两个或多个具有相同ID的div。
您可以在http://jsfiddle.net/mqpsppxm/上查看简单的实施