在添加之前检查类是否已经分配

在 jQuery 中,是否建议在添加一个类之前检查一个类是否已经分配给一个元素?会有什么影响吗?

例如:

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

还是这样就够了:

$('label').addClass('baz');
45099 次浏览

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

具体来说,您可以在 源头中找到支票

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

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

This question got my attention following 另一个被标记为这个的复制品.

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

你试图通过避免不必要的检查来优化,在这方面你必须注意以下几个因素:

  1. 通过 JavaScript 操作 DOM 元素,不可能在 class 属性中有重复的类名。如果在 HTML 中有 class="collapse",则调用 Element.classList.add("collapse");将不会添加额外的 collapse类。我不知道底层的实现,但我认为它应该足够好了。
  2. JQuery 在其 addClassremoveClass实现中进行了一些必要的检查(我检查了 < strong > 源代码 )。对于 addClass,在做了一些检查之后,如果一个类存在,JQuery 不会再试图添加它。类似地,对于 removeClass,JQuery 沿着 cur.replace( " " + clazz + " ", " " );行做一些事情,只有在类存在的情况下才会删除它。

值得注意的是,JQuery 在其 removeClass实现中进行了一些优化,以避免无意义的重新呈现。是这样的

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

So the best 微观 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 油门 the scroll event handling.

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