63 votes

Est-ce que j'ai vraiment besoin de vérifier si un élément existe avec jQuery?

Récemment, j'ai eu une question sur la manière de vérifier correctement si un élément existe avec jQuery. J'ai trouvé la réponse ici:

https://learn.jquery.com/using-jquery-core/faq/how-do-i-test-whether-an-element-exists/

En résumé:

if ( $( "#myDiv" ).length ) {
    // Faire quelque chose
}

Un collègue avec qui je travaille dit que la manière correcte de vérifier devrait être:

if ($( "#myDiv" ) && $( "#myDiv" ).length ) {
    // Faire quelque chose
}

Cela a-t-il de l'importance ? Je veux dire, du point de vue des performances ou de la latence, est-ce qu'ils fonctionnent de la même manière ?

Aussi:

$( "#myDiv" ).show();
$( "#myDiv" ).hide();
$( "#myDiv" ).val('');

Dans ce type de fonctions jQuery, il semble qu'aucune vérification if n'est nécessaire car elles ne lèveront pas d'erreur si #myDiv n'existe pas, n'est-ce pas ?

Pour ce que ça vaut, j'utilise jQuery 1.6.4.

104voto

T.J. Crowder Points 285826

Un collègue avec qui je travaille dit que la bonne façon de vérifier devrait être :

if ($( "#myDiv" ) && $( "#myDiv" ).length ) {
    //do something
}

Il a tort, du moins en ce qui concerne la partie $( "#myDiv" ) &&. La méthode $(selector) de jQuery retourne toujours un objet, qui est toujours truthy par définition. Donc cette partie est inutile et re-requêter le DOM pour rien.

Je veux dire au niveau des performances ou de la latence, est-ce qu'ils sont égaux ?

Re-querer le DOM pour rien est une perte de temps, mais la plupart du temps cela n'a pas d'impact observable, et surtout pas pour les sélecteurs ID comme $("#myDiv") qui sont optimisés par jQuery en appels à getElementById (qui est ultra-rapide). Donc d'une part, oui c'est du travail supplémentaire inutile. D'autre part, les navigateurs sont tellement rapides de nos jours que vous avez probablement d'autres préoccupations. Mais c'est probablement du code supplémentaire inutile, ce qui est le plus gros problème.

Concernant le point général : jQuery est basé sur des ensembles. Cela signifie que les opérations sur des ensembles sans éléments ne font rien. Par exemple :

$(".foo").addClass("bar");

...est une non-opération (pas une erreur) si aucun élément .foo n'est dans le DOM.

Donc vérifiez la length quand vous voulez savoir si vous avez trouvé des éléments. Si cela ne vous importe pas et que vous voulez simplement effectuer des opérations sur eux s'ils sont là, faites simplement l'opération (avec une importante mise en garde1).

Donc en gros, il y a trois scénarios :

  1. Vous savez que les éléments seront là, donc la vérification est inutile
    \=> pas de vérification

  2. Vous ne savez pas si les éléments seront là, mais cela vous importe peu et vous voulez simplement opérer sur eux si ils sont là
    \=> pas de vérification

  3. Vous voulez savoir si les éléments sont là pour une autre raison
    \=> faites la vérification


1 Voici la mise en garde importante : si vous appelez une fonction jQuery qui retourne quelque chose d'autre qu'un objet jQuery (par exemple, val() ou offset() ou position(), etc.), quand vous l'appelez sur un ensemble vide, cela retournera typiquement undefined (l'exception est text(), qui retournera "" [text() n'est pas comme les autres à plusieurs égards; c'en est un]). Donc écrire du code qui suppose naïvement que ces choses retourneront ce que vous attendez, même quand l'ensemble est vide, vous causera des problèmes.

Par exemple :

if ($(".foo").offset().top > 20)

...va générer une erreur s'il n'y a pas d'éléments .foo, car offset() retournera undefined, pas un objet.

Mais cela est bon :

$(".foo").closest(".bar").toggleClass("baz"):

...car même s'il n'y a pas de .foo, closest() retournera un autre ensemble jQuery vide, et appeler toggleClass() dessus ne fera rien.

Donc quand vous manipulez un accesseur qui ne retourne pas un objet jQuery, si vous ne savez pas avec certitude que vous manipulez un ensemble contenant au moins un élément, vous avez besoin de plus de défense, par exemple :

var offset = $(".foo").offset();
if (offset && offset.top > 20)

Encore une fois, la plupart des accesseurs (qui ne retournent pas d'objets jQuery) fonctionnent ainsi, y compris val(), offset(), position(), css(), ...

28voto

Rob M. Points 5205

Il est important, et $( "#myDiv" ).length est mieux car il ne lance pas document.getElementById('myDiv') deux fois. Si vous mettiez en cache le sélecteur, cela aurait beaucoup moins d'importance :

var $myDiv = $( "#myDiv" );

if ($myDiv && $myDiv.length) { ... }

Cependant, les sélecteurs jQuery renvoient toujours quelque chose qui sera interprété comme "truthy", donc

if ($('#myDiv')) { 

est une vérification inutile.

5voto

Drew Kennedy Points 3159

Un collègue avec qui je travaille dit que la bonne façon de vérifier devrait être :

if ($( "#myDiv" ) && $( "#myDiv" ).length ) {
    //faire quelque chose
}

Cette déclaration est fausse. La vérification de $( "#myDiv" ).length retournerait simplement 0 s'il n'est pas trouvé. Pour être certain, voici un exemple de code avec à la fois un id trouvé, et un deuxième id qui n'est pas présent :

console.log("Nombre de #myDiv trouvés : " + $("#myDiv").length);
console.log("Nombre de #AnotherMyDiv trouvés : " + $("#AnotherMyDiv").length);

3voto

hobberwickey Points 1393

Dépend de ce que vous faites après l'instruction if.

Pensez-y de cette façon. Tout appel de sélecteur jquery retourne un objet jquery qui est essentiellement un tableau étendu avec différentes méthodes. Lorsque vous appelez quelque chose comme $(".mes-elements").show() il bouclera sur les éléments que $(".mes-elements") a retournés et appliquera .show() à ceux-ci puis retournera le même objet jquery, c'est ainsi que jquery enchaîne.

Si vous faites juste des choses chaînables alors non, vous n'avez pas besoin de faire la vérification if. Parce que toutes les méthodes ultérieures ne feront qu'une boucle équivalente à for (var i=0; i<0; i++){ } ce qui signifie qu'il ne se passera rien. Si vous avez une grande chaîne et que vous l'exécutez dans une grande boucle qui doit être très performante, vous voudrez peut-être faire la vérification if, mais généralement cela n'aura pas vraiment d'importance d'un point de vue performance.

Si cependant, vous faites quelque chose qui générera une erreur ou vous donnera un mauvais résultat si l'élément n'existe pas alors oui, utilisez la vérification if. Par exemple

function addHeight() {
  var height1 = $("#div1").height(),
      height2 = $("#div2").height();

  $("#otherDiv").css({ top: height1 + height2 });
}

Si div1 ou div2 n'existent pas, otherDiv aura son top défini sur NaN ce qui n'est probablement pas ce que vous recherchez. Dans ce cas, vous voudriez vérifier que à la fois div1 et div2 existent réellement, mais vous n'avez toujours pas vraiment à vérifier pour otherDiv car si cela n'existe pas, rien ne se passera de toute façon.

-1voto

Flautarian Points 6

Il est plus simple de vérifier si elle existe et, si nous voulons plus d'informations sur l'objet, nous ne recevrons pas d'erreur d'objet nul.

if (!!$( "#myDiv" )) {
    //faire quelque chose
}

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