客户端表过滤

时间:2009-12-23 14:30:28

标签: jquery jquery-selectors

正如标题所述。我正在使用jQuery来做魔术。我对选择器使用了自定义Contains扩展名,如下所示:

jQuery.expr[':'].Contains = function(a, i, m) {
   return jQuery(a).text().toUpperCase().indexOf(m[3].toUpperCase()) >= 0;
};

我在互联网上找到了。它工作正常。我正在将它与以下内容结合使用:

$("#txtSurname, #txtForename").keyup(function() {
    var forenameVal = $("#txtForename").val();
    var surnameVal = $("#txtSurname").val();
    $("#tblEmployees tr").show();
    if (forenameVal.length > 0) { $("#tblEmployees tr td:nth-child(1):not(:Contains('" + forenameVal + "'))").parent().hide(); }
    if (surnameVal.length > 0) { $("#tblEmployees tr td:nth-child(2):not(:Contains('" + surnameVal + "'))").parent().hide(); }
});

然而,这是非常低效的,并且有500行的表格,它极大地挣扎。在写高效选择器时,我的jQuery uber-ninja技能不如下一个开发人员那么好,因此我想知道是否有更好的方法来做到这一点?

3 个答案:

答案 0 :(得分:2)

一个建议是重用常见的jQuery对象,这应该减少开销:

$("#txtSurname, #txtForename").keyup(function() {
    var forenameVal = $("#txtForename").val();
    var surnameVal = $("#txtSurname").val();
    var  t = $("#tblEmployees tr");
    t.show();
    if (forenameVal.length > 0) { t.find("td:nth-child(1):not(:Contains('" + forenameVal + "'))").parent().hide(); }
    if (surnameVal.length > 0) { t.find("td:nth-child(2):not(:Contains('" + surnameVal + "'))").parent().hide(); }
});

答案 1 :(得分:1)

这是jQuery匹配的硬选择器。你要求它做很多不必要的工作。

虽然标准CSS选择器可以允许您在具有querySelectorAll的较新浏览器中利用浏览器的快速CSS匹配实现,但自定义jQuery选择器总是会变慢。我建议如果你遇到速度问题,你可能最好将匹配的代码自己编写为显式JavaScript,而不是将其作为选择器。

使用显式匹配代码也意味着您可以将字符串连接的丑陋性丢失到选择器Contains('" + forenameVal + "')中,当输入名称中存在'等特殊字符时,这将会出错。 '经常以现实世界的名字出现。

例如。 (另):

var forenameVal= $('#txtForename').val().toUpperCase();
var surnameVal= $('#txtSurname').val().toUpperCase();
var table= document.getElementById('table');
for (var i= table.rows.length; i-->0;) {
    var row= table.rows[i];
    row.className= (
        row.cells[0].firstChild.data.toUpperCase().indexOf(forenameVal)!==-1 &&
        row.cells[1].firstChild.data.toUpperCase().indexOf(surnameVal)!==-1
    )? '' : 'hidden';
}

请注意,这依赖于具有单个Text节点子节点的每个名称单元格来获取data。如果不是这种情况(名称单元格可能包含其他内容,或者根本没有内容,甚至不包含空格),则必须使用$(row.cells[0]).text(),但这也会更慢。

它还依赖className来键入隐藏(你将.hidden { display: none; }放在样式表中)以避免隐藏表行的一些困难。你可以把它变成if (...) $(row).show(); else $(row).hide();,但这又让jQuery做了一些工作。

答案 2 :(得分:0)

您是否考虑过改进自定义选择器(请参阅以下内容)

How do I determine an HTML input element type upon an event using jQuery?

What useful custom jQuery selectors have you written?

var $item = jQuery(a);
return ($item.attr("type") == "input") &&
        $item.text().toUpperCase().indexOf(m[3].toUpperCase()) >= 0;