Check if class already assigned before adding

JqueryAddclass

Jquery Problem Overview


In jQuery, is it recommended to check if a class is already assigned to an element before adding that class? Will it even have any effect at all?

For example:

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

When in doubt if class baz has already been assigned to label, would this be the best approach:

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

or would this be enough:

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

Jquery Solutions


Solution 1 - Jquery

Just call addClass(). jQuery will do the check for you. If you check on your own, you are doubling the work, since jQuery will still run the check for you.

Solution 2 - Jquery

A simple check in the console would have told you that calling addClass multiple times with the same class is safe.

Specifically you can find the check in the source

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

Solution 3 - Jquery

This question got my attention following another which was marked as a duplicate of this one.

This answer summarises the accepted answer with a little added detail.

You're trying to optimise by avoiding an unnecessary check, in this regard here are factors you must be aware of:

  1. it's not possible to have duplicate class names in the class attribute by means of manipulating a DOM element via JavaScript. If you have class="collapse" in your HTML, calling Element.classList.add("collapse"); will not add an additional collapse class. I don't know the underlying implementation, but I suppose it should be good enough.
  2. JQuery makes some necessary checks in its addClass and removeClass implementations (I checked the source code). For addClass, after making some checks and if a class exists JQuery doesn't try to add it again. Similarly for removeClass, JQuery does somethings along the line of cur.replace( " " + clazz + " ", " " ); which will remove a class only if it exists.

Worth noting, JQuery does some optimisation in its removeClass implementation in order to avoid a pointless re-rendering. It goes like this

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

So the best micro optimisation you could do would be with the aim of avoiding function call overheads and the associated implementation checks.

Say you want to toggle a class named collapse, if you are totally in control of when the class is added or removed, and if the collapse class is initially absent, then you may optimise as follows:

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

As an aside, if you're toggling a class due to changes in scroll position, you are highly recommended to throttle the scroll event handling.

Solution 4 - Jquery

$("label")
  .not(".foo")
  .addClass("foo");

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMuleskinnerView Question on Stackoverflow
Solution 1 - Jqueryjmar777View Answer on Stackoverflow
Solution 2 - JqueryRaynosView Answer on Stackoverflow
Solution 3 - JqueryIgwe KaluView Answer on Stackoverflow
Solution 4 - Jqueryטאבו ישראל שרות לקוחותView Answer on Stackoverflow