Check if class already assigned before adding
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
开发者_C百科 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');
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:
- 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, callingElement.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. - JQuery makes some necessary checks in its
addClass
andremoveClass
implementations (I checked the source code). ForaddClass
, after making some checks and if a class exists JQuery doesn't try to add it again. Similarly forremoveClass
, JQuery does somethings along the line ofcur.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");
精彩评论