I'm very new to JS, and really don't understand a lot of it. Trying to learn as I go.
I'm trying to add some new divs to buttons to style them to look like the rest of the buttons on my site as I cant edit the plugins HTML. I've managed to successfully do this for one button. But it won't work for the other buttons. I've tried to read into it and it looks like because I am using getElementsByClassName its only selecting the first button and not the others.
So I dont know if this is right or not and correct me if it ain't. but I think I need to set up a Node loop? so that getElementsByClassName doesn't just select the first node on the page. However I got no Idea how to set up a node loop and reading about it is just confusing me more.
Can someone help and possibly explain this to me so I can make sense of it for future reference.
Thanks
This is the code I currently have, I just don't know how to make it target all elements with that class rather than just the first element with that class.
var btnSwirls = document.createElement('div');
btnSwirls.id = 'dbtb-button-swirl-wrap';
btnSwirls.className = 'dbtb-button-swirl-wrap';
document.getElementsByClassName("dbtb-add-btn-assets")[0].appendChild(btnSwirls);
CodePudding user response:
const btnSwirls = document.createElement('div');
btnSwirls.id = 'dbtb-button-swirl-wrap';
btnSwirls.className = 'dbtb-button-swirl-wrap';
document.getElementsByClassName("dbtb-add-btn-assets").forEach(element => {
element.appendChild(btnSwirls);
})
learn more about forEach()
: https://www.youtube.com/watch?v=SXb5LN_opbA
learn more about arrow functions: https://www.youtube.com/watch?v=h33Srr5J9nY
learn more about var
, let
, and const
: https://www.youtube.com/watch?v=9WIJQDvt4Us
CodePudding user response:
You need to loop over all the elements. You only access the first of many elements using [0]
.
There are multiple ways to do this. Here are two ways to do it using a sample application which just toggles a class (adds/ removes a class) every two seconds.
#1 - Use querySelectorAll()
and forEach()
You can use querySelectorAll()
to get a NodeList
of HTML elements which match the given CSS selector .someClass
.
Notice that the CSS selector requires a
.
before a class name.
window.addEventListener("DOMContentLoaded", e => {
const allElements = document.querySelectorAll(".someClass");
// add/ remove class every 2 seconds
setInterval(() => {
// loop over all elements and add/ remove a class
allElements.forEach(element => {
element.classList.toggle("anotherClass");
});
}, 2000)
})
.someClass {
padding: 20;
background-color: black;
color: white;
margin: 5px;
}
.anotherClass {
border: 2px solid red;
}
<div >div 1</div>
<div >div 2</div>
<div >div 3</div>
<div >div 4</div>
#2 - Use getElementsByClassName()
and for .. of ...
loop
Alternatively you can use getElementsByClassName()
which returns a HTMLCollection
. You can then use a for ... of ...
loop to iterate over all the elements in the collection.
Notice that here for the
getElementsByClassName()
call we MUST NOT use a.
before the class name.
window.addEventListener("DOMContentLoaded", e => {
const allElements = document.getElementsByClassName("someClass");
// loop
setInterval(() => {
// loop over all elements and add/ remove a class
for (const element of allElements) {
element.classList.toggle("anotherClass");
}
}, 2000)
})
.someClass {
padding: 20;
background-color: black;
color: white;
margin: 5px;
}
.anotherClass {
border: 2px solid red;
}
<div >div 1</div>
<div >div 2</div>
<div >div 3</div>
<div >div 4</div>
Please note: You should use
DOMContentLoaded event
so you wait till the HTML document is ready before you try to access the DOM.
CodePudding user response:
First of all, you are handling an "array" of elements. For that, you'd need a loop to iterate over the array.
you shouldn't be using this document.getElementsByClassName("dbtb-add-btn-assets")[0] <-- because this part [0] denotes that you are targeting the first element in the array, hence 0, since all arrays start with the index 0; i.e. [0, 1, 2, 3, ...] indices
so for iterating over an array you can either use a (for loop) or a (for of) loop
for loop:
let dbtb_add_btn_assets = document.getElementsByClassName("dbtb-add-btn-assets"); //you are assigning a variable to the array;
for(let i = 0; i < dbtb_add_btn_assets.length; i ) {
var btnSwirls = document.createElement('div');
btnSwirls.id = 'dbtb-button-swirl-wrap';
btnSwirls.className = 'dbtb-button-swirl-wrap'; //create btnswirls per iteration of the loop
dbtb_add_btn_assets[i].appendChild(btnSwirls);
}
the i is the current index of the loop, the i part of the for loop will automatically add 1 to itself upon executing the statement inside the for loop and ends when i is not less than the dbtb_add_btn_assets length. Length meaning the number of elements inside the array.
for of:
let dbtb_add_btn_assets = document.querySelectorAll('.dbtb-add-btn-assets'); //personally I'd use querySelectorAll instead of getElementsByCLassName just add . for classes # for ids
for(let dbtb of dbtb_add_btn_assets) { //name whatever variable you want to use
var btnSwirls = document.createElement('div');
btnSwirls.id = 'dbtb-button-swirl-wrap';
btnSwirls.className = 'dbtb-button-swirl-wrap'; //create btnswirls per dbtb
dbtb.appendChild(btnSwirls);
}