2009-12-23 1 views
2

Как указано в заголовке. Я использую 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 не так велики, как следующий разработчик, когда дело доходит до написания эффективных селекторов, поэтому мне было интересно, есть ли лучший способ сделать это?

ответ

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(); } 
}); 
+0

Все еще довольно чертовски медленно, к сожалению, хотя предложение имеет смысл. – Kezzer

+0

Вы пытались вытащить селектор «: not (: Contains» только для того, чтобы увидеть, есть ли там узкое место? –

1

Это довольно жесткий селектор для jQuery для соответствия. Вы просите его сделать много ненужной работы.

В то время как стандартные селектор CSS может позволить вам использовать быструю реализацию CSS-совместимости браузера в новых браузерах с querySelectorAll, пользовательские селектора 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'; 
} 

Примечания это зависит от каждого имени ячейки, имеющей одного ребенка текстового узла, чтобы получить data от. Если это не так (ячейка имени может содержать другой контент или вообще не содержать контент, даже не пустое пространство), вам придется использовать вместо этого $(row.cells[0]).text(), но это также будет медленнее.

Он также полагается на имя класса для скрытия ключа (вы должны положить .hidden { display: none; } в таблицу стилей), чтобы избежать некоторых трудностей при скрытии строк таблицы. Вместо этого вы можете превратить его в if (...) $(row).show(); else $(row).hide();, но опять же это заставляет jQuery делать немного больше работы.