JavaScript实现DOM数字滚动动画需用requestAnimationFrame+线性插值,计算增量与进度并Math.round取整;支持Intl.NumberFormat格式化;可加easeOutCubic缓动、多动画同步;注意类型转换、DOM挂载及安全更新。

用 JavaScript 实现 DOM 元字滚动动画,核心是**在指定时间内,让数字从起始值平滑过渡到目标值**,通常配合 requestAnimationFrame 或 setInterval 控制帧率,再通过更新元素的 textContent 或 innerText 实现视觉变化。
基础实现:requestAnimationFrame + 线性插值
这是最推荐的方式,性能好、控制精准、兼容性佳。
- 计算总变化量(
target - start)和每帧应增加的增量(基于持续时间和帧率) - 用
requestAnimationFrame循环更新数值,直到达到目标值 - 对数值做
Math.floor或toFixed(n)处理,避免小数干扰显示(如计费、得分等场景常需整数)
示例代码:
function animateNumber(element, start, target, duration = 2000) {
const startTime = performance.now();
const increment = target - start;
<p>function update(currentTime) {
const elapsed = currentTime - startTime;
const progress = Math.min(elapsed / duration, 1); // 0~1
const value = start + increment * progress;</p><pre class="brush:php;toolbar:false;">element.textContent = Math.round(value); // 或 value.toFixed(1)
if (progress <p>}</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill6235" title="Java Maven Code Review"><img
src="https://img.php.cn/upload/skill/000/000/081/179084711841712.jpg" alt="Java Maven Code Review" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill6235" title="Java Maven Code Review" class="overflowclass">Java Maven Code Review</a>
<p class="overflowclass">审查Java Maven项目(ZIP压缩包或GitLab仓库URL),检查代码规范、命名、模块边界、可维护性问题以及重复代码。</p>
</div>
<a rel="nofollow" href="/xiazai/skill6235" title="Java Maven Code Review" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div><p>requestAnimationFrame(update);
}</p><p>// 使用
const el = document.getElementById('counter');
animateNumber(el, 0, 12345, 2500);
</p>支持格式化:带千分位、小数、前缀/后缀
真实项目中,数字常需格式化(如 12,345.67、¥99.99),可在更新时动态处理:
- 用
Intl.NumberFormat实现本地化格式(推荐):new Intl.NumberFormat().format(value) - 手动拼接前缀/后缀:
`¥${value.toFixed(2)}` - 注意:频繁格式化不影响性能,但避免在每次渲染中重复创建
Intl.NumberFormat实例(可提前定义)
增强体验:缓动函数与多数字同步
线性变化略显生硬,加入缓动(easing)更自然;多个数字同时滚动时,保持节奏一致也很重要。
- 替换
progress为缓动函数,例如“easeOutCubic”:1 - Math.pow(1 - progress, 3) - 所有动画共享同一
requestAnimationFrame循环(用单个主 tick 管理多个动画),减少重排压力 - 可封装成类或 Hook(如 React 中的
useAnimatedNumber),支持暂停、重置、回调
注意事项与避坑点
实际开发中容易忽略但影响体验的细节:
- 确保目标值是数字类型,字符串如
"1000"需先parseInt或parseFloat - 元素需已挂载到 DOM,否则
textContent赋值无效(可用element.isConnected判断) - 避免用
innerHTML更新纯数字——有 XSS 风险且不必要 - 移动端注意开启
will-change: transform或使用transform: translateZ(0)提升合成层(对超大数字列表滚动有帮助)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










