繁体   English   中英

如何实现同时在所有计数器处停止的计数?

[英]How can I implement a countup that stops at all counters simultaneously?

我已经实现了一个动画到数据目标的计数。 如何调整计数器以使所有计数器同时停止?

还是有更好的方法来实现这一点?

 function animationEffect(){ const counters = document.querySelectorAll('.counter'); const speed = 2000; counters.forEach((counter) => { const updateCount = () => { const target = + counter.getAttribute('data-target'); const count = + counter.innerText; const inc = target / speed; if(count < target) { counter.innerText = Math.ceil(count + inc); setTimeout(updateCount, 1); } else { counter.innerText = target; } } updateCount(); }); }
 <div class="counter" data-target="299" onmouseover="animationEffect()">0</div> <div class="counter" data-target="1299" onmouseover="animationEffect()">0</div> <div class="counter" data-target="99" onmouseover="animationEffect()">0</div>

我不知道它是否有帮助,但是当我更改此行时我得到了它: const inc = target / speed;

为此: const inc = 1/(speed / target);

并摆脱Math.ceil()因为这个const speed = 2000; 这实际上是一个创建浮动值的步骤。 也许尝试更小的speed

编辑多一点调整,我们有一个没有浮动值的平滑答案>:D

 function animationEffect(){ if(animationEffect.called){return null} animationEffect.called=true //these 2 lines prevent this function from being called multiple times to prevent overlapping //the code works without these lines though so remove them if u don't want them const counters = document.querySelectorAll('.counter'); const incrementConstant = 2; //the higher the number the faster the count rate, the lower the number the slower the count rate const speed = 2000; counters.forEach((counter) => { const updateCount = () => { const target = + counter.getAttribute('data-target'); counter.storedValue=counter.storedValue||counter.innerText-0; //saving a custom value in the element(the floating value) const count = + counter.storedValue; //accessing custom value(and rounding it) const inc = incrementConstant/(speed / target); //the math thanks to @Tidus if(count < target) { counter.storedValue=count+inc counter.innerText = Math.round(counter.storedValue); setTimeout(updateCount, 1); } else { counter.innerText = target; } } updateCount(); }); }
 <div class="counter" data-target="299" onmouseover="animationEffect()">0</div> <div class="counter" data-target="1299" onmouseover="animationEffect()">0</div> <div class="counter" data-target="99" onmouseover="animationEffect()">0</div>

如果将此代码粘贴到代码顶部并运行,当您记录window.activeTimers时,您将看到定义了数百个计时器。 这是因为每次调用updateCount时,您都在为 updateCount 设置一个新计时器。 虽然您的animationEffect function 就像您的程序的主要 function 一样,但如果您每次将鼠标悬停在您的计数器上时调用它,它将设置新的计时器,这意味着每次都更快地更新您的计数器。 总而言之,您目前根本无法控制。

对于定期调用,您应该使用setInterval 它需要一个 function 和一个延迟参数(还有可选参数。您可以查看文档)。 repeatedly calls a function or executes a code snippet, with a fixed time delay between each call (From Mozilla docs) 它还返回一个间隔 ID,以便您以后可以取消它(这意味着我们可以控制它)。

所以在你的情况下,你应该做的第一件事就是停止对animationEffect的onmouseover调用并添加一个按钮来停止执行updateCounters。

<div class="counter" data-target="299">0</div>
<div class="counter" data-target="1299">0</div>
<div class="counter" data-target="99">0</div>
<button id="stop">Stop</button>

在分配变量countersspeed之后,我们可以定义一个数组来保存间隔的 ID,以便以后取消它们。

  const counters = document.querySelectorAll(".counter");
  const speed = 2000;
  
  const cancelButton = document.getElementById('stop')
  const countIntervals = [];
  cancelButton.addEventListener('click', () => {
    countIntervals.forEach(interval => clearInterval(interval))
  })

如您所见,我为我们的按钮定义了一个事件侦听器。 当您单击它时,它将迭代countIntervals中的间隔 ID 并清除这些间隔。 为简单起见,我没有实现诸如暂停和重置之类的功能,并且尽量不要过多地更改您的代码。 您可以稍后进行实验。

现在您应该做的第一件事是在 if 语句中注释或删除setTimeout行。 然后我们将返回的区间 ID 推送到我们的数组countIntervals

  counters.forEach((counter) => {
    const updateCount = () => {
      const target = +counter.getAttribute("data-target");
      const count = +counter.innerText;
      const inc = target / speed;
      if (count < target) {
        counter.innerText = Math.ceil(count + inc);
        // setTimeout(updateCount, 1);
      } else {
        counter.innerText = target;
      }
    };
    countIntervals.push(setInterval(updateCount, 10))
  });

现在,一旦您按下Stop按钮,您的计数器就会停止。 我忽略了速度功能,但如果您了解setInterval ,您可以轻松实现它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM