Home > Software engineering >  JavaScript setTimeout parameters and selectors
JavaScript setTimeout parameters and selectors

Time:12-05

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.

  • Related