Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if class already assigned before adding

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.


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 ] + " ";
}

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.


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