user9645391
user9645391

Reputation:

How to add class just once in JavaScript?

I have written the code below :

var reachedElement = document.querySelector(`[data-index='${elementInfo.elementIndex}']`);
var elementClass = reachedElement.className.split(' ');

for (var className of elementClass) {
  if (className !== 'myClass') {
    reachedElement.className += ' myClass';
  }
}

Description : I select an element and by using split method I put all classes in an array and I check if whether or not they have myClass. If they have I don't want to do anything but if not, I want to add my class, My problem is that when my element doesn't have any classes or have more that one class, It doesn't work properly and add as many as the array have values. What's wrong? Picture : This is my problem

Upvotes: 0

Views: 1186

Answers (2)

Daniel Beck
Daniel Beck

Reputation: 21485

Element.classList has add(), remove(), and toggle() functions that will take care of this for you:

let reachedElements = document.querySelectorAll(`[data-index='1']`); // switched to querySelectorAll, so you can do more than one element at a time
reachedElements.forEach(function(el) {
  el.classList.add('myClass'); // duplicates on the same element are automatically prevented
})

// proof:
console.log(document.getElementById('container').innerHTML)
.myClass {
  color: #0F0
}
<div id="container">
  <div data-index="1" class="myClass foo bar baz">x</div>
  <div data-index="1" class="myClass">x</div>
  <div data-index="1">x</div>
  <div data-index="1">x</div>
  <div data-index="1" class="foo bar">x</div>
</div>

Old browsers

IE versions 9 and below are the only still-extant browsers that don't support classList (IE10 has partial support, sufficient for the above.) If you need to support old IE, you'll need to iterate through the class string much as you're already doing -- but don't add the new classname every time an old class name exists, which is how you're getting those duplicates. I haven't tested but this should work in IE9, which supports querySelectorAll -- if you need IE8 or below you'll need a historian to help you, I've forgotten all that stuff:

var reachedElements = document.querySelectorAll(`[data-index='1']`); 

reachedElements.forEach(function(el) {
   // read the classes into an array:
   var classArr = el.className.split(' ');
   // add the new class if it's not already in the array:
   if (classArr.indexOf("myClass") === -1) {
      classArr.push("myClass");
      el.className = classArr.join(" ");
   }
})

// proof:
console.log(document.getElementById('container').innerHTML)
.myClass {
  color: #0F0
}
<div id="container">
  <div data-index="1" class="myClass foo bar baz">x</div>
  <div data-index="1" class="myClass">x</div>
  <div data-index="1">x</div>
  <div data-index="1">x</div>
  <div data-index="1" class="foo bar">x</div>
</div>

Upvotes: 1

Existent
Existent

Reputation: 717

In case you need an example, here it goes. Going by your question, you can do something like:

var reachedElements = document.querySelectorAll(`[data-index='${elementInfo.elementIndex}']`);
reachedElements.forEach((element) => element.classList.add("myClass"))

This will add the class only if it doesn't exist. You can read the docs for classList here

Upvotes: 1

Related Questions