I am trying to select elements in the loop and pass them to setTimeout.
Why doesn't the following work as it is supposed to?
Is it because el.querySelector('.b') is slower than setTimeout?
var ids = document.querySelectorAll('.a'),
span
ids.forEach(el => {
span = el.querySelector('.b')
setTimeout(function() {
span.classList.add('visible');
}, 20, span);
})
.visible{
color:red;
}
<p ><span >1</span></p>
<p ><span >2</span></p>
<p ><span >3</span></p>
CodePudding user response:
Just don't use var
and declare variables in their scope
const ids = document.querySelectorAll('.a')
ids.forEach(el => {
const span = el.querySelector('.b')
setTimeout(function() {
span.classList.add('visible');
}, 20, span);
})
.visible {
color: red;
}
<p ><span >1</span></p>
<p ><span >2</span></p>
<p ><span >3</span></p>
CodePudding user response:
In the code you provided, the span
variable is overwritten on each iteration of the forEach
loop, so when the callback function is executed, it will always reference the same element (the last one selected by querySelector). To fix this, you can move the querySelector call inside the callback function, like this:
var ids = document.querySelectorAll('.a'),
span
ids.forEach(el => {
setTimeout(function() {
var span = el.querySelector('.b')
span.classList.add('visible');
}, 2000);
})
.visible{
color:red;
}
<p ><span >1</span></p>
<p ><span >2</span></p>
<p ><span >3</span></p>
This should work as expected. I've increased the delay to make the change more visible.