纯css无法实现滚动数字增长动画,必须用javascript控制数值演进并配合css transform实现视觉滚动;需用requestanimationframe、performance.now()、intersectionobserver等机制确保精准、高效、按需执行。

纯 CSS 无法实现滚动数字增长动画,必须用 JavaScript 控制数值演进节奏,并配合 CSS 的 transform 实现视觉滚动位移。所谓“滚动”,本质是数字列上下滑动的错觉,不是文字自动递增。
用 requestAnimationFrame 替代 setInterval 避免跳帧
直接用 setInterval 累加数字,在页面失焦、低帧率设备或后台标签页中极易跳值甚至提前结束。而 requestAnimationFrame 绑定浏览器刷新节奏,天然适配当前帧率(如 60fps),且会自动暂停。
- 起始时间必须用
performance.now(),不能用Date.now()——后者会被系统时间调整干扰 - 进度计算要加
Math.min(elapsed / duration, 1),防止单帧延迟导致超调、显示负数或溢出目标 - 每帧只写一次
innerText或textContent,避免高频 DOM 写入触发重排 - 函数应闭包保存自身状态,多个数字实例互不干扰
数字进视口才启动:用 IntersectionObserver 控制触发时机
在 DOMContentLoaded 里直接跑动画,用户还没滚动到数字区域,动画就结束了。尤其在数据看板、统计模块等中下部位置,必须等元素可见再激活。
-
threshold: 0.1表示元素 10% 高度可见即触发,比 0.5 更早响应滚动 - 触发后立刻调用
observer.unobserve(el),避免重复执行 - 若数字是动态插入的(如 AJAX 渲染),需在插入后手动调用
observer.observe(el)
处理带单位或后缀的数字,比如 “+1234” 或 “2.8万”
原始文本常含非数字字符,直接取 innerText 会导致 NaN。得先剥离再还原。
- 用
textContent.replace(/\D/g, '')提纯数字,但要注意小数点和负号;更稳妥的是parseFloat(textContent)或正则/-?\d+\.?\d*/ - 保留原始后缀(如 +、万、%)需存到
dataset或data-suffix - 动画结束时拼回去:
el.innerText = finalValue + (el.dataset.suffix || '')
真正难的不是让数字变大,而是让多位数字列同步滚动、对齐、不抖动——每个数字列的高度、内部数字容器的总高度、transform 偏移量的负号方向,三者必须严格匹配,差一点就会错位或卡顿。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











