Estoy trabajando en un sitio que tiene muchos contadores y tengo un problema para obtener la [velocidad de datos] para crear diferentes velocidades de contador dependiendo del número en ese contador.
Cuando ejecuto este ciclo forEach, siempre obtengo la misma velocidad, la función obtiene el número más grande de todos los contadores.
¿Alguna idea de dónde me equivoqué?
const counters = document.querySelectorAll('.counter'); let i = 0; const io = new IntersectionObserver(entries => { entries.forEach(entry => { const finalNumber = entry.target.innerText; const speed = +entry.target.dataset.speed; if (entry.isIntersecting) { entry.target.innerText = i; const interval = setInterval(() => { entry.target.innerText = i += speed; if (i >= finalNumber) { entry.target.innerText = finalNumber; clearInterval(interval); } }, 10) } }) }) counters.forEach(item => io.observe(item)) <h1 class="counter" data-speed="1">1000</h1> <h1 class="counter" data-speed="2">1000</h1> <h1 class="counter" data-speed="3">1000</h1> <h1 class="counter" data-speed="4">1000</h1> <h1 class="counter" data-speed="5">1000</h1>No sé cómo ayudarlo con su código, pero programé una forma alternativa de lograr esto que puede ser útil.
const elements = document.querySelectorAll('.counter') elements.forEach((el, key) => { let speed = Number(elements[key].getAttribute('speed')) setCounter(el, speed, 1000) }) function setCounter(element, speed, limit){ let count = 0 let interval = setInterval(() => { count = (count >= limit) ? limit : count + speed if(count === limit) clearInterval(interval) element.innerHTML = count }, 1) } <h3 class="counter" speed='6'></h1> <h3 class="counter" speed='7'></h1> <h3 class="counter" speed='8'></h1> <h3 class="counter" speed='9'></h1>Has declarado la i globalmente. Entonces, todas las entradas compartirán el mismo texto interno, ya que i se está operando globalmente. Para solucionar esto, debe declarar la variable i para cada entrada, dentro de las entries.forEach . Esto asegurará que cada entrada tenga su propia 'i' localmente y operará en consecuencia.
const counters = document.querySelectorAll('.counter'); const io = new IntersectionObserver(entries => { entries.forEach(entry => { let i = 0; const finalNumber = entry.target.innerText; const speed = +entry.target.dataset.speed; if (entry.isIntersecting) { entry.target.innerText = i; const interval = setInterval(() => { i = i + speed; entry.target.innerText = i; if (i >= finalNumber) { entry.target.innerText = finalNumber; clearInterval(interval); } }, 10) } }) }) counters.forEach(item => io.observe(item)) <h1 class="counter" data-speed="1">1000</h1> <h1 class="counter" data-speed="2">1000</h1> <h1 class="counter" data-speed="3">1000</h1> <h1 class="counter" data-speed="4">1000</h1> <h1 class="counter" data-speed="5">1000</h1>