61 votes

Est-ce que jQuery fait tout type de cache de "sélecteurs"?

Par exemple, le premier morceau de code effectuera-t-il une recherche complète deux fois, ou est-il assez intelligent pour mettre en cache les résultats si aucune modification DOM n'a eu lieu?

 if ($("#navbar .heading").text() > "") {
  $("#navbar .heading").hide();
}
 

et

 var $heading = $("#navbar .heading");

if ($heading.text() > "") {
  $heading.hide();
}
 

Si le sélecteur est plus complexe, j'imagine que c'est un succès non trivial.

29voto

gnarf Points 49213

Cachez toujours vos sélections!

Il est inutile d'appeler constamment $( selector ) avec le même sélecteur.

Ou presque toujours ... Vous devez généralement conserver une copie en cache de l'objet jQuery dans une variable locale, sauf si vous vous attendez à ce qu'elle ait changé ou si vous n'en avez besoin qu'une seule fois.

 var element = $("#someid");

element.click( function() {

  // no need to re-select #someid since we cached it
  element.hide(); 
});
 

16voto

Neil C. Obremski Points 3747

jQuery ne le fait pas, mais il est possible d'assigner des variables dans votre expression, puis de les réutiliser dans des expressions ultérieures. Alors, cachez votre exemple ...

 if ((cached = $("#navbar .heading")).text() > "") {
  cached.hide();
}
 

L'inconvénient est que cela rend le code un peu plus volumineux et difficile à maîtriser.

14voto

JoeBloggs Points 1284

Ce n'est pas tant une question de " est-il?', mais " peut-il?', et non, il ne peut pas - vous pourriez avoir ajouté des éléments correspondants pour les DOM depuis la requête de la dernière exécution. Ce serait le résultat mis en cache rassis, et jQuery aurait pas (sensible) de façon à le dire à d'autres que l'exécution de la requête à nouveau.

Par exemple:

$('#someid .someclass').show();
$('#someid').append('<div class="someclass">New!</div>');
$('#someid .someclass').hide();

Dans cet exemple, le nouvel élément ne serait pas caché si il n'y avait aucune mise en cache de la requête, serait - il masquer uniquement les éléments qui ont été révélé plus tôt.

13voto

Aleksandr Makov Points 657

Je viens de faire une méthode pour résoudre ce problème:

 var cache = {};

function $$(s)
{
    if (cache.hasOwnProperty(s))
    {
        return $(cache[s]);
    }

    var e = $(s);

    if(e.length > 0)
    {
        return $(cache[s] = e);
    }

}
 

Et ça marche comme ça:

 $$('div').each(function(){ ... });
 

Les résultats sont précis, à ma connaissance, sur la base de cette vérification simple:

 console.log($$('#forms .col.r')[0] === $('#forms .col.r')[0]);
 

NB, cela va casser votre implémentation MooTools ou toute autre bibliothèque qui utilise la notation $$ .

9voto

Peter Boughton Points 49510

Je ne pense pas que ce soit le cas (bien que je n'aie pas envie de lire trois mille cinq cent lignes de JavaScript pour le moment, pour le savoir).

Cependant, ce que vous faites n'a pas besoin de plusieurs sélecteurs - cela devrait fonctionner:

 $("#navbar .heading:not(:empty)").hide();
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X