如何实现带独立增量的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
相关产品推荐
相关产品推荐

