JavaScript實(shí)現(xiàn)余額數(shù)字滾動(dòng)效果
1.實(shí)現(xiàn)背景
上周在一個(gè)完成任務(wù)領(lǐng)取紅包的活動(dòng)需求中,需要實(shí)現(xiàn)一個(gè)用戶點(diǎn)擊按鈕彈出領(lǐng)取紅包彈窗后,在關(guān) 閉彈窗返回原來(lái)的頁(yè)面時(shí),頁(yè)面余額數(shù)字部分要展示一個(gè)每一位數(shù)字滾動(dòng)后的效果。
因?yàn)橹皼]做過(guò)這樣的效果,一開始也不知道要如何實(shí)現(xiàn),本來(lái)想在GitHub上找一下相關(guān)的庫(kù),看到一個(gè)最高star的庫(kù),但發(fā)現(xiàn)它是依賴jQuery的,而且不可以npm包引入。感覺就很沒有必要,本來(lái)項(xiàng)目是react框架的,就是要盡量少的操作DOM,為了解決這個(gè)滾動(dòng)就要引入jQuery,感覺不太合適。所以我決定還是自己實(shí)現(xiàn),先看了一下別人的思路,然后自己再去實(shí)現(xiàn)。
2.實(shí)現(xiàn)思路
其實(shí)就是將傳入的帶滾動(dòng)的n位數(shù)字拆分成每一個(gè)要滾動(dòng)的數(shù),然后動(dòng)態(tài)的創(chuàng)建裝著滾動(dòng)到每一位相應(yīng)數(shù)字的容器,然后放入傳入的目標(biāo)容器中。滾動(dòng)到每一位相應(yīng)的數(shù)字的實(shí)現(xiàn)可以通過(guò)動(dòng)態(tài)創(chuàng)建從0到相應(yīng)數(shù)字的間隔數(shù)的div,div的內(nèi)容分別為對(duì)應(yīng)的數(shù)字,就像一個(gè)豎直寫著從0-n的長(zhǎng)紙條,然后拉著它在指定時(shí)間內(nèi)從0上拉到目標(biāo)數(shù)字。
3.實(shí)現(xiàn)過(guò)程
既然要封裝,還是寫成class的形式吧,話不多說(shuō),直接上代碼吧
/**
* 實(shí)現(xiàn)數(shù)字滾動(dòng)的效果的類
*/
class DigitScroll {
constructor(options) {
//獲取容器的DOM,沒有則拋出錯(cuò)誤
this.container = document.querySelector(options.container);
if (!this.container) {
throw Error("no container");
}
this.container.style.overflow = "hidden";
this.container.style.display = "flex";
//可視容器高度 也是滾動(dòng)間隔距離,容器要設(shè)置高度,否則默認(rèn)30px
this.rollHeight = parseInt(getComputedStyle(this.container).height) || 30;
this.container.style.height = this.rollHeight + "px";
}
roll(num) {
// 將傳入的要滾動(dòng)的數(shù)字拆分后初始化每一位數(shù)字的容器
this.initDigitEle(num);
const numEles = this.container.querySelectorAll(".single-num");
// 遍歷生成每一位數(shù)字的滾動(dòng)隊(duì)列,如滾動(dòng)到7,則生成內(nèi)容為0,1,2,3,4,5,6,7的7個(gè)div,用于滾動(dòng)動(dòng)畫
[...numEles].forEach((numEle, index) => {
const curNum = 0;
let targetNum = Number(this.numberArr[index]);
if (curNum >= targetNum) {
targetNum = targetNum + 10;
}
let cirNum = curNum;
// 文檔碎片,拼湊好后一次性插入節(jié)點(diǎn)中
const fragment = document.createDocumentFragment();
// 生成從0到目標(biāo)數(shù)字對(duì)應(yīng)的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) {
// 數(shù)字拆分位數(shù)
const numArr = num.toString().split("");
// 文檔碎片,拼湊好后一次性插入節(jié)點(diǎn)中
const fragment = document.createDocumentFragment();
numArr.forEach((item) => {
const el = document.createElement("div");
// 數(shù)字是要滾動(dòng)的,非數(shù)字如.是不滾動(dòng)的
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);
// 存儲(chǔ)滾動(dòng)的數(shù)字
this.numberArr = numArr.filter((item) => /[0-9]/.test(item));
}
}
到此這篇關(guān)于JavaScript實(shí)現(xiàn)余額數(shù)字滾動(dòng)效果的文章就介紹到這了,更多相關(guān)JavaScript實(shí)現(xiàn) 數(shù)字滾動(dòng) 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
瀏覽器切換到其他標(biāo)簽頁(yè)或最小化js定時(shí)器是否準(zhǔn)時(shí)測(cè)試
這篇文章主要為大家介紹了瀏覽器切換到其他標(biāo)簽頁(yè)或最小化是js定時(shí)器是否準(zhǔn)時(shí)的測(cè)試詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07
Javascript調(diào)用XML制作連動(dòng)下拉列表框
Javascript調(diào)用XML制作連動(dòng)下拉列表框...2006-06-06
js c++ vue方法與數(shù)據(jù)交互通信示例
這篇文章主要為大家介紹了js c++ vue方法與數(shù)據(jù)交互通信示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08
微信小程序 監(jiān)聽手勢(shì)滑動(dòng)切換頁(yè)面實(shí)例詳解
這篇文章主要介紹了微信小程序 監(jiān)聽手勢(shì)滑動(dòng)切換頁(yè)面實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-06-06
Javascript實(shí)現(xiàn)的分頁(yè)函數(shù)
Javascript實(shí)現(xiàn)的分頁(yè)函數(shù)...2006-12-12

