You need to enable JavaScript to run this app. 如何实现带独立增量的Javascript计数器并保持DRY代码原则
优惠活动
大模型
产品
解决方案
定价
更多

如何实现带独立增量的Javascript计数器并保持DRY代码原则

解决方案

问题根因

原有代码中所有计数器的增量都按照target / 500的固定规则计算,所有计数器共用同一个除数参数,相当于默认所有计数器都要在500次刷新内完成计数,数值小的计数器增量极小、数值大的计数器增量极大,会出现进度不一致的问题。

优化实现(符合DRY原则)

我们通过给每个计数器新增自定义属性的方式配置独立参数,所有计数器共用同一套更新逻辑,无需重复开发功能。

调整后的HTML

新增data-duration属性自定义每个计数器的动画总时长(单位:毫秒),也可以根据需求换成data-increment直接配置增量值:

<!-- 可自定义每个计数器的总时长 -->
<div class="counter" data-target="6" data-duration="1000"></div>
<div class="counter" data-target="6000" data-duration="2000"></div>
<div class="counter" data-target="12000" data-duration="3000"></div>

调整后的JS代码

const counter = function() {
  const counters = document.querySelectorAll(".counter");
  const REFRESH_INTERVAL = 1; // 固定刷新间隔为1ms

  counters.forEach((counterEl) => {
    // 每个计数器仅初始化一次自身配置,互不影响
    const target = +counterEl.dataset.target;
    const duration = +counterEl.dataset.duration || 2000; // 未配置时默认2秒完成
    const totalSteps = duration / REFRESH_INTERVAL;
    const increment = target / totalSteps; // 独立增量,仅和当前计数器配置有关

    counterEl.innerText = 0; // 初始化计数起点

    function updateCounter() {
      const current = +counterEl.innerText;
      if (current < target) {
        counterEl.innerText = `${Math.ceil(current + increment)}`;
        setTimeout(updateCounter, REFRESH_INTERVAL);
      } else {
        counterEl.innerText = target;
      }
    }
    updateCounter();
  });
}

counter();

方案说明

  • 全量计数器复用同一套更新逻辑,无冗余代码,符合DRY原则
  • 每个计数器的增量在初始化阶段仅计算一次,完全独立互不干扰
  • 可灵活扩展配置项,如需直接指定增量只需新增data-increment属性,替换增量计算逻辑为const increment = +counterEl.dataset.increment || 1即可。

内容的提问来源于stack exchange,提问作者Brontes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.20 15:15:03