2009-12-23 6 views
2

Comme l'indique le titre. J'utilise jQuery pour faire la magie. Je l'ai utilisé une extension personnalisée Contains aux sélecteurs comme suit:Filtrage de la table côté client

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

que je trouve sur la interwebs. Ça fonctionne bien. Je l'utilise en conjonction avec les éléments suivants:

$("#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(); } 
}); 

Cependant, cela est très inefficace et avec une table de 500 lignes, il se bat énormément. Mes compétences de jQuery uber-ninja ne sont pas aussi bonnes que celles du développeur suivant quand il s'agit d'écrire des sélecteurs efficaces, donc je me demandais s'il y avait une meilleure façon de faire ça?

Répondre

2

Une suggestion est de réutiliser l'objet jQuery commun, ce qui devrait réduire les frais généraux:

$("#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

Encore assez sacrément lent malheureusement, bien que la suggestion ait un sens. – Kezzer

+0

avez-vous essayé de sortir le sélecteur ": not (: Contient) juste pour voir si c'est là que se trouve le goulot d'étranglement? –

1

C'est plutôt un sélecteur difficile pour jQuery. Vous lui demandez de faire beaucoup de travail inutile. Alors que les sélecteurs CSS standard peuvent vous permettre de tirer parti de la mise en œuvre rapide de la mise en correspondance CSS du navigateur dans les nouveaux navigateurs qui ont querySelectorAll, les sélecteurs jQuery personnalisés seront toujours lents. Je suggérerais que si vous avez des problèmes de vitesse, vous feriez mieux d'écrire le code correspondant en tant que JavaScript explicite plutôt que de le coder en sélectionneurs. L'utilisation d'un code de correspondance explicite signifie également que vous pouvez perdre la laideur de la concaténation de chaînes dans le sélecteur Contains('" + forenameVal + "'), ce qui ne fonctionnera pas lorsque des caractères spéciaux tels que ' sont présents dans le nom d'entrée. ' est assez souvent présent dans les noms du monde réel.

par ex. (Non testé):

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'; 
} 

RemarqueCet repose sur chaque cellule de nom ayant un seul enfant de nœud de texte pour obtenir le data de. Si ce n'est pas le cas (une cellule de nom peut contenir un autre contenu, ou aucun contenu du tout, pas même un espace), vous devrez utiliser $(row.cells[0]).text() à la place, mais cela sera également plus lent.

Il s'appuie également sur un nom de classe pour hiddenness clé (vous devez mettre .hidden { display: none; } dans la feuille de style) pour éviter certaines des difficultés de masquer les lignes de table. Vous pouvez à la place le transformer en un if (...) $(row).show(); else $(row).hide(); mais encore une fois, jQuery fait un peu plus de travail.