2

我有一个表格,每一行都包含一个单元格,里面是复选框和该复选框的标签。

我正在尝试根据输入的文本隐藏行。

基本上这是名称列表,我想过滤/隐藏那些不包含输入文本的名称。

这是我的功能:

$(function () {
$('#user_name').keyup(function () {
    if ($.trim($('input#user_name').val()) == '') {
        $('table.myList >tbody >tr').each(function (index, value) {
            $(this).css("display", "block");
        });
    } else {
        $('table.myList >tbody >tr').each(function (index, value) {
            if ($(this).find('td > label').length > 0) {
                if ($(this).find('td > label').html().toLowerCase().indexOf($.trim($('input#user_name').val()).toLowerCase()) >= 0) {
                    $(this).css("display", "block");
                } else {
                    $(this).css("display", "none");
                }
            }
        });
    }
});
});

此代码有效,如果我的表有 40 条记录,它的速度很快,但是当我将列表增加到 500 时,它会变慢并在一段时间后使我的浏览器崩溃。

我正在寻找一种方法来改进此代码以更快地工作。

这是模型代码的链接:http: //jsfiddle.net/gGxcS/

==更新==

这是我基于@scessor 和@nnnnnn 的答案的最终解决方案:

$(function () {

var $tableRows = $('table.myList tr');
var lastInput = '';

$('#user_name').keyup(function () {
    var sValue = $.trim($('input#user_name').val());
    if(lastInput==sValue) return;
    if (sValue == '') {
        $tableRows.show();
    } else {
        $tableRows.each(function () {
            var oLabel = $(this).find('label');
            if (oLabel.length > 0) {
                if (oLabel.text().toLowerCase().indexOf(sValue.toLowerCase()) >= 0) {
                    $(this).show();
                } else {
                    $(this).hide();
                }
            }
        });
        lastInput=sValue;
    }
});

$('img.removeSelections').click(function () {
    $('table.myList input[type="checkbox"]').prop("checked", false);
})
});
4

2 回答 2

2

你能测试这段代码(有很多元素)吗?

$(function () {
    $('#user_name').keyup(function () {
        var sValue = $.trim($('input#user_name').val());
        if (sValue == '') {
            $('table.myList tr').show();
        } else {
            $('table.myList tr').each(function() {
                var jThis = $(this);
                var oLabel = jThis.find('label');
                if (oLabel.length > 0) {
                    if (oLabel.text().toLowerCase().indexOf(sValue.toLowerCase()) >= 0) {
                        jThis.show();
                    } else {
                        jThis.hide();
                    }
                }
            });
        }
    });
});
  • 不要两次调用具有相同参数的函数(例如$.trim($('input#user_name').val());)。
  • 使用短选择器。
  • 仅在必要时使用每个 jquery(例如这里不需要:)$('table.myList >tbody >tr').each(function (index, value) {

=== 更新 ===

如果有人坚持backspacelong,它将tr一次又一次地设置所有 s 可见。为了防止这种情况,您可以检查最后一个值是否等于当前值。如果是真的,什么也不做。

=== 更新 ===

要取消选中所有复选框,这取决于您的 jQuery 版本。

使用 jQuery 1.6 及更高版本:
$('table.myList input[type="checkbox"]').prop("checked", false);
之前:
$('table.myList input[type="checkbox"]').attr("checked", false);

于 2012-07-03T07:11:42.427 回答
2

我建议你缓存你的 jQuery 对象——假设你想在每次击键时处理我会在 keyup 处理程序之外缓存表行对象。此外,当您可以在外部调用一次时,不要在.each()循环内部调用函数 - 例如,无需$.trim($('input#user_name').val()).toLowerCase()在每次.each()迭代时都调用它们。

$(function () {
    var $tableRows = $('table.myList >tbody >tr');

    $('#user_name').keyup(function () {
        var searchStr = $.trim($('input#user_name').val()).toLowerCase();
        if (searchStr === '') {
            $tableRows.css("display", "block");
        } else {
            $tableRows.each(function (index, value) {
                var $this = $(this),
                    $label =$this.find('td > label');
                if ($label.length > 0) {
                    if ($label.html().toLowerCase().indexOf(searchStr) >= 0) {
                        $this.css("display", "block");
                    } else {
                        $this.css("display", "none");
                    }
                }
            });
        }
    });
});

演示:http: //jsfiddle.net/gGxcS/3/

于 2012-07-03T07:29:46.203 回答