Reputation: 3
I feel like this should be simple enough but I tend to overthink things. I simply want to add new classes to only the container-1
elements. The classes need to be numbered to differentiate them. Bonus for multiple methods & explaining in detail as I'd like to learn how to do this properly.
Example:
<div class="scroller">
<div class="container-1 newClass1"></div>
<div class="container-1 newClass2"></div>
<div class="container-2"></div>
<div class="container-1 newClass3"></div>
<div class="container-2"></div>
</div>
As the title says, the amount can be random. So it needs to read & apply to all container-1
within the scroller
.
Upvotes: 0
Views: 70
Reputation: 14363
You can use querySelector
(just to teach people who still use jQuery
) to query for DOM elements
.
You can then use Array.forEach
to iterate over the list, and use $node.classList.add
to append a class name.
Just for the purpose of the example:
window.onload = function onload () {
document.getElementById('btn-add').addEventListener('click', add, true);
document.getElementById('btn-remove').addEventListener('click', remove, true);
}
function add(e) {
updateFocus(e.target);
const list = document.querySelectorAll('.container-1');
list.forEach((item, i) => item.classList.add(`newClass-${i}`));
}
function remove(e) {
updateFocus(e.target);
const list = document.querySelectorAll('.container-1');
list.forEach((item, i) => item.classList.remove(`newClass-${i}`));
}
function updateFocus(el){
document.querySelectorAll('.active').forEach((i) => i.classList.remove('active'));
el.classList.add('active');
}
.scroller {
height: 100%;
width: 100%;
}
div[class*="container"] {
display: inline-block;
border: 1px solid blue;
width: 20px;
height: 20px;
margin: 2px;
}
div[class*="newClass-"] {
border: 1px solid yellow;
}
.active {
border: 3px solid red;
font-weight: bold;
}
<div class="scroller">
<div class="container-1"></div>
<div class="container-1"></div>
<div class="container-2"></div>
<div class="container-1"></div>
<div class="container-2"></div>
</div>
<button id="btn-add">add newClass-* to container-1</button>
<button id="btn-remove">remove newClass-* to container-1</button>
Otherwise it is just one line of code
document.querySelectorAll('.container-1');
.forEach((item, i) => item.classList.add(`newClass-${i}`));
Upvotes: 0
Reputation: 41
Well, one method I can think of is:
let selectedContainers = Array.from(document.querySelectorAll('.container-1'));
selectedContainers.map((container, i)=>{
container.classList.add(`newClass${++i}`)
})
What's going on here is that you're selecting all the divs with the container-1 class and creating an array from the NodeList. Then you're mapping through the array to access each element. Using template strings, you add a class name with a dynamic variable being the index of the container. You could use other variables and just increment them after, but I think the index is the easiest solution. Also, the reason I used ++i
is to avoid getting a class with a zero index e.g newClass0
Upvotes: 0
Reputation: 4770
You can create an array of all the elements having class name 'container-1
using document.getElementsByClassName
and the spread operator(...
). Spread operator is used here because getElementsByClassName
returns a HTMLCollection. So to iterate over it easily using a forEach
we need to convert it to an array. Once converted, we could iterate over it and add newClass
class to every element. To get the number to be added to the end of each newClass
we use the 2nd argument to forEach
which is index of the current element.
const containerOneDivs = [...document.getElementsByClassName('container-1')];
containerOneDivs.forEach((div, i) => div.className += ` newClass${i+1}`);
Upvotes: 0
Reputation: 21
Here is some js, which get all elements by class name "container-1". After that in for loop, it will add class "newClass" with counter mark to each of the element with this class.
var elements = document.getElementsByClassName("container-1");
for(var i = 0; i < elements.length; i++){
elements[i].classList.add("newClass" + (i+1));
}
Upvotes: 1