JavaScript 实现余额数字滚动效果
本文介绍如何在 React 项目中实现余额数字滚动效果。通过自定义类封装,将数字拆分为单个字符,利用动态创建的 div 容器模拟竖直长纸条,配合 CSS 动画在指定时间内滚动至目标数字。该方法避免引入 jQuery 等重型库,保持轻量级 DOM 操作,适用于红包领取等场景的数字变化展示。
1.实现背景
上周在处理一个领取红包的活动需求时,需要实现一个功能:当用户点击按钮弹出领取红包弹窗,关闭弹窗返回原页面时,页面余额数字部分要展示一个每一位数字滚动后的效果。由于之前没有做过这样的效果,一开始也不清楚如何实现。原本打算在 GitHub 上寻找相关的库,虽然看到了 star 数最高的一个库,但发现它依赖 jQuery,而且无法通过 npm 包引入。考虑到项目本身是基于 react 框架,为了保持轻量级并尽量减少 DOM 操作,如果为了解决滚动效果而引入 jQuery 显得不太合适。因此,我决定自己实现,先参考了别人的思路,然后着手开发。
2.实现思路
核心思路是将传入的包含 n 位数字的字符串拆分成每一个需要滚动的数字,然后动态创建包含滚动到每一位相应数字的容器,并将其放入传入的目标容器中。实现滚动到每一位相应数字的方法,可以通过动态创建从 0 到相应数字的间隔数的 div,div 的内容分别为对应的数字,就像一个竖直写着从 0 到 n 的长纸条,然后拉着它在指定时间内从 0 上拉到目标数字。
3.实现过程
既然要封装,还是写成 class 的形式吧,话不多说,直接上代码吧
/**
* 实现数字滚动的效果的类
*/
class DigitScroll {
constructor(options) {
//获取容器的DOM,没有则抛出错误
this.container = document.querySelector(options.container);
if (!this.container) {
throw Error("no container");
}
this.container.style.overflow = "hidden";
this.container.style.display = "flex";
//可视容器高度 也是滚动间隔距离,容器要设置高度,否则默认30px
this.rollHeight = parseInt(getComputedStyle(this.container).height) || 30;
this.container.style.height = this.rollHeight + "px";
}
roll(num) {
// 将传入的要滚动的数字拆分后初始化每一位数字的容器
this.initDigitEle(num);
const numEles = this.container.querySelectorAll(".single-num");
// 遍历生成每一位数字的滚动队列,如滚动到7,则生成内容为0,1,2,3,4,5,6,7的7个div,用于滚动动画
[...numEles].forEach((numEle, index) => {
const curNum = 0;
let targetNum = Number(this.numberArr[index]);
if (curNum >= targetNum) {
targetNum = targetNum + 10;
}
let cirNum = curNum;
// 文档碎片,拼凑好后一次性插入节点中
const fragment = document.createDocumentFragment();
// 生成从0到目标数字对应的div
while (targetNum >= cirNum) {
const ele = document.createElement("div");
ele.innerHTML = cirNum % 10;
cirNum++;
fragment.appendChild(ele);
}
numEle.innerHTML = "";
numEle.appendChild(fragment);
//重置位置
numEle.style.cssText +=
"-webkit-transition-duration:0s;-webkit-transform:translateY(0)";
setTimeout(() => {
numEle.style.cssText += `-webkit-transition-duration:1s;-webkit-transform:translateY(${
-(targetNum - curNum) * this.rollHeight
}px);`;
}, 50);
});
}
// 初始化容器
initDigitEle(num) {
// 数字拆分位数
const numArr = num.toString().split("");
// 文档碎片,拼凑好后一次性插入节点中
const fragment = document.createDocumentFragment();
numArr.forEach((item) => {
const el = document.createElement("div");
// 数字是要滚动的,非数字如.是不滚动的
if (/[0-9]/.test(item)) {
el.className = "single-num";
el.style.height = this.rollHeight + "px";
el.style.lineHeight = this.rollHeight + "px";
} else {
el.innerHTML = item;
el.className = "no-move";
el.style.verticalAlign = "bottom";
}
// el.style.float='left';
fragment.appendChild(el);
}, []);
this.container.innerHTML = "";
this.container.appendChild(fragment);
// 存储滚动的数字
this.numberArr = numArr.filter((item) => /[0-9]/.test(item));
}
}
到此这篇关于 JavaScript 实现余额数字滚动效果的文章就介绍到这了,更多相关 JavaScript 实现 数字滚动 内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!
D3.js 处理大规模数据点的性能优化策略
2026-11-05 15:37:25
JS实现网页摄像头实时扫码:结合getUserMedia与jsQR教程
2026-11-05 15:27:28
D3.js v5 迁移到 v7 的 API 变更与注意事项
2026-11-05 11:57:17
使用 animate.js 实现多元素协同的序列动画
2026-11-04 22:27:53
JS拖拽排序时怎么添加平滑动画效果?FLIP技术实战
2026-11-04 10:12:22
