This question's answer (addClass to an element with that class already?) indicates that when using jQuery there is no problem that arises if you .addClass('foo')
on an element that already has a class of foo
.
I am curious of the same is true for the element.classList
method of .add
.
In particular I have a function called update()
that is called whenever a range slider is updated. This can occur many times a second. Depending on the value passed to update()
I add and remove certain classes to an element.
If the value falls in a certain range consecutively I end up adding the same class over and over again.
My question is can I allow elem.classList.add('foo')
to run, let's say, 50 times in one second without experiencing any negative consequences to user experience, memory, processor use, etc. Is this an acceptable practice?
Thanks.
if (!el.classList.contains("foo")) {
el.classList.add("foo");
}
el.classList.add("foo");
.classList
property is a DOMTokenList object.DOMTokenList
defines it as a container with case-sensitive, whitespace-trimmed, unique items.DOMTokenList
(such as DOMTokenList.add()
) automatically trim any surrounding whitespace and remove duplicates from the set.add()
the same className twice, it won't add the duplicate.Here's an example:
<span class=" d d e f"></span>
// Output: DOMTokenList(3)Â ["d", "e", "f", value: " d d e f"]
// As you can see, it only contains the unique values.
console.log(document.querySelector("span").classList);
// Try to add a duplicate value.
document.querySelector("span").classList.add("e");
// Output: DOMTokenList(3)Â ["d", "e", "f", value: "d e f"]
// As you can see again, it only contains the unique values.
console.log(document.querySelector("span").classList);
// In fact, the act of duplicates being detected while trying
// to add more classes, results in the "class" attribute itself
// being cleaned up and trimmed:
// Output: "d e f"
console.log(document.querySelector("span").getAttribute("class"));
Alright, so why, exactly, shouldn't you use .contains()
to "avoid calling .add()
when unnecessary"? Because:
.contains()
function and the .add()
functions use the exact same native code for searching through the unique set to see if it contains the class..add()
will search through the set, and if it already contains the className, the function simply aborts. And yes, it sometimes also cleans up the "class" HTML attribute if necessary, but only if necessary..contains()
before .add()
and you end up adding the className, you just ran the search for the className twice, via two different functions.if (!el.classList.contains("foo")) { ... }
boilerplate around every attempt to add classes..add()
to add a class (even if it already exists), and .remove()
to remove a class (even if it's already missing).Don't waste your keyboard's life and programmer eyes on clunky boilerplate. Only use .contains()
if you actually care about finding out if an element has a certain class. 😊
DOMTokenList
has many other helpful functions:.replace(oldToken, newToken)
: Replaces an existing token with a new token. If the old token doesn't exist, .replace()
returns false
immediately, without adding the new token to the token list..toggle(token [, force])
: Removes a given token from the list and returns false
, or if token doesn't exist it's instead added and the function returns true
. Alternatively, if you include the force
parameter: If included, turns the toggle into a one way-only operation. If set to false
, then token will only be removed, but not added. If set to true
, then token will only be added, but not removed.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With