使用JavaScript快速过滤记录列表

时间:2015-03-05 11:34:41

标签: javascript jquery html dom

我在网页上有一个包含大约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>

问题是,当我点击“搜索”按钮时,会有很长的延迟,直到我得到匹配结果的列表。有没有更好的方法来过滤列表?

3 个答案:

答案 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');
        }
    }
}

示例:http://jsfiddle.net/29ubpjgk/

答案 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();
    }
}

一个测试示例http://jsfiddle.net/vtds899r/

答案 2 :(得分:0)

问题是你正在迭代记录,而拥有10000它可能非常慢,所以我的建议是稍微改变结构,所以你不必迭代:

  1. customer-wrapper上定义列表的所有css功能 并将其设为所有列表元素的父div

  2. 当您的ajax请求添加元素时,创建一个包含替换下划线空格的名称的变量,让我们将其称为underscore_name

  3. 将名称添加到列表中:

  4. var customerHtml = "<div id='"+underscore_name+'>" + name + "</div>";

    列表中的每个元素都有一个唯一的ID,几乎就是&#34;与名称相同,列表的所有元素都位于customer-wrapper类下的相同级别

    1. 对于搜索,您可以使用用户输入替换下划线的空格并输入变量,例如searchable_id,并使用Jquery:
    2. $('#'+searchable_id).siblings().hide();

      siblings会隐藏与 searchable_id 相同级别的其他元素。

      唯一的问题是,如果有两个或更多重复名称的情况,因为它会尝试创建两个或多个具有相同ID的div。

      您可以在http://jsfiddle.net/mqpsppxm/上查看简单的实施