web-dev-qa-db-fra.com

Vérifiez si la classe est déjà assignée avant d'ajouter

Dans jQuery, est-il recommandé de vérifier si une classe est déjà affectée à un élément avant d'ajouter cette classe? Cela aura-t-il même un effet?

Par exemple:

<label class='foo'>bar</label>

En cas de doute si la classe baz a déjà été affectée à label, serait-ce la meilleure approche:

var class = 'baz';
if (!$('label').hasClass(class)) {
  $('label').addClass(class);
}

ou cela suffirait-il:

$('label').addClass('baz');
99
Muleskinner

Il suffit d'appeler addClass(). jQuery fera le chèque pour vous. Si vous vérifiez par vous-même, vous doublez le travail, puisque jQuery va encore exécuter le contrôle pour vous.

161
jmar777

Une simple vérification dans la console vous aurait indiqué qu'appeler addClass plusieurs fois avec la même classe est sans danger.

Plus précisément, vous pouvez trouver le chèque dans la source

if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) {
  setClass += classNames[ c ] + " ";
}
46
Raynos

Cette question a attiré mon attention après une autre qui était marquée comme une copie de celle-ci }.

Cette réponse résume la réponse acceptée avec un petit détail ajouté.

Vous essayez d'optimiser en évitant les vérifications inutiles. À cet égard, vous devez prendre en compte certains facteurs:

  1. il n'est pas possible d'avoir des noms de classe en double dans l'attribut class en manipulant un élément DOM via JavaScript. Si vous avez class="collapse" dans votre code HTML, appeler Element.classList.add("collapse"); n’ajoutera pas de classe supplémentaire collapse. Je ne connais pas l'implémentation sous-jacente, mais je suppose que cela devrait suffire.
  2. JQuery effectue les vérifications nécessaires dans ses implémentations addClass et removeClass (j'ai vérifié le code source ). Pour addClass, après avoir effectué quelques vérifications et si une classe existe, JQuery n'essaie pas de l'ajouter à nouveau. De même pour removeClass, JQuery effectue certaines actions le long de la ligne de cur.replace( " " + clazz + " ", " " );, ce qui ne supprimera une classe que si elle existe.

Il est à noter que JQuery optimise son implémentation removeClass afin d’éviter un nouveau rendu inutile. Ça va comme ça

...
// only assign if different to avoid unneeded rendering.
finalValue = value ? jQuery.trim( cur ) : "";
if ( elem.className !== finalValue ) {
    elem.className = finalValue;
}
...

Ainsi, la meilleure optimisation que vous puissiez faire dans le cadre de micro consiste à éviter les frais généraux liés aux appels de fonctions et les contrôles d’implémentation associés.

Supposons que vous souhaitiez basculer vers une classe nommée collapse, si vous maîtrisez totalement le moment où la classe est ajoutée ou supprimée, et si la classe collapse est initialement absente, vous pouvez optimiser comme suit:

$(document).on("scroll", (function () {
    // hold state with this field
    var collapsed = false;

    return function () {
        var scrollTop, shouldCollapse;

        scrollTop = $(this).scrollTop();
        shouldCollapse = scrollTop > 50;

        if (shouldCollapse && !collapsed) {
            $("nav .branding").addClass("collapse");
            collapsed = true;

            return;
        }

        if (!shouldCollapse && collapsed) {
            $("nav .branding").removeClass("collapse");
            collapsed = false;
        }
    };
})());

Soit dit en passant, si vous changez de classe en raison de changements de position de défilement, il est fortement recommandé de étrangler la gestion des événements de défilement.

4
Igwe Kalu
$("label")
  .not(".foo")
  .addClass("foo");