Reputation: 41
This is frustrating.
I am currently doing a practice and I'd like to add a class and remove another class on a div with the class "sap". I have 3 divs with the same class and I intend to use a loop to get all elements with the same class but it doesn't seem to be working and I don't know why.
I am using only vanilla JS.
Can anyone help me out? Thanks for any help rendered.
HTML:
<button onclick="boot()">show</button>
<div class=panel>
<div id="container" class="sap">
<div class="content"><span>unveil</span></div>
<div class="smooth">
</div>
</div>
<div class="sap">
<div class="content"><span>unveil</span></div>
<div class="smooth">
</div>
</div>
<div class="sap">
<div class="content"><span>unveil</span></div>
<div class="smooth">
</div>
</div>
</div>
JS:
function boot(){
for(var i=0;i<=3;i++){
var box=document.getElementsByClassName("sap");
if(box[i].classList.contains("content")){
box[i].classList.add("flush");
}}
}
Upvotes: 0
Views: 1526
Reputation: 5708
The code you provided works, except there is no div with class content
and sap
at the same time so when you run the snippet below you won't see any changes (no class will be added to any element):
function boot() {
var box = document.getElementsByClassName("sap");
for(var i=0; i < box.length; i++) {
if(box[i].classList.contains("content")) {
box[i].classList.add("flush");
}
}
}
.flush {
font-weight: bold;
color: #09f;
}
<button onclick="boot()">show</button>
<div class=panel>
<div id="container" class="sap">
<div class="content"><span>unveil</span></div>
<div class="smooth"></div>
</div>
<div class="sap">
<div class="content"><span>unveil</span></div>
<div class="smooth"></div>
</div>
<div class="sap">
<div class="content"><span>unveil</span></div>
<div class="smooth">
</div>
</div>
</div>
In case you wanted to add the class to an element of class sap
that has a child element with class content
:
function boot() {
var box = document.getElementsByClassName("sap");
for(var i=0; i < box.length; i++) {
if(box[i].querySelector('.content') !== null) {
box[i].classList.add("flush");
}
}
}
.flush {
font-weight: bold;
color: #09f;
}
<button onclick="boot()">show</button>
<div class=panel>
<div id="container" class="sap">
<div class="content"><span>unveil</span></div>
<div class="smooth"></div>
</div>
<div class="sap">
<div class="content"><span>unveil</span></div>
<div class="smooth"></div>
</div>
<div class="sap">
<div class="content"><span>unveil</span></div>
<div class="smooth">
</div>
</div>
</div>
Upvotes: 0
Reputation: 122906
It's generally not a good idea to use inline event handlers.
You can use the more modern document.querySelectorAll
, spread its (array like) result into an Array
and perform the wanted action on that. Or, even shorter, select all .sap > .content
in one go and perfom the action. Something like:
document.addEventListener("click", boot);
function boot(evt) {
// --------------------------------------------------------------------------------
// just for this demo snippet
[...document.querySelectorAll(".flush, .flushAlt")]
.forEach(elem =>
elem.classList.remove("flush","flushAlt"));
// --------------------------------------------------------------------------------
if (evt.target.dataset.action === "boot") {
[...document.querySelectorAll(".sap")] // all div.sap
.forEach(elem =>
[...elem.querySelectorAll(".content")] // all div.content *within* div.sap
.forEach(content =>
content.classList.add("flush")))
} else if (evt.target.dataset.action === "bootAlt") {
// all div.content *within* div.sap in one go
[...document.querySelectorAll(".sap > .content")]
.forEach(content =>
content.classList.add("flushAlt"))
}
}
.flush {
color: red;
background-color: yellow;
width: 100px;
margin: 4px;
padding: 2px;
text-align: center;
}
.flushAlt {
color: white;
background-color: brown;
width: 100px;
margin: 4px;
padding: 2px;
text-align: center;
}
<button data-action="boot">show</button>
<button data-action="bootAlt">show (alternative)</button>
<div class=panel>
<div id="container" class="sap">
<div class="content"><span>unveil</span></div>
<div class="smooth">
</div>
</div>
<div class="sap">
<div class="content"><span>unveil</span></div>
<div class="smooth">
</div>
</div>
<div class="sap">
<div class="content"><span>unveil</span></div>
<div class="smooth">
</div>
</div>
</div>
Upvotes: 1
Reputation: 50291
Take this var box=document.getElementsByClassName("sap");
outside the loop. This will give the collection of the html elements with this class sap
. Then you will like to iterate this collection , so you need not to hard code the number 3. Note in you code you did <=3
. It will be <
but not <=
. Since <=
the index starts from 0, so <=
will also try to match 4th element which is not there.
Then get the first child of the div.sap
using children
function boot() {
var box = document.getElementsByClassName("sap");
for (var i = 0; i < box.length; i++) {
const firstChild = box[i].children[0]
if (firstChild.classList.contains("content")) {
firstChild.classList.add("flush");
}
}
}
.sap {
border: 1px solid red;
}
.content {
color: green;
}
.flush {
font-size: 20px;
color: blue;
}
<button onclick="boot()">show</button>
<div class=panel>
<div id="container" class="sap">
<div class="content"><span>unveil</span></div>
<div class="smooth">
</div>
</div>
<div class="sap">
<div class="content"><span>unveil</span></div>
<div class="smooth">
</div>
</div>
<div class="sap">
<div class="content"><span>unveil</span></div>
<div class="smooth">
</div>
</div>
</div>
Upvotes: 0