今天要來做的是動態計數效果,隨著固定的時間遞增固定的數字上去,因為時間設得很短,所以視覺上看起來像是連續的,如圖中那樣!
all.min.css
知識點 | 使用說明 |
---|---|
data-* Attritube | 自訂義屬性 |
@media | 設置中斷點,這裡只有設定一個寬度的斷點 |
知識點 | 使用說明 |
---|---|
getAttribute() | 取得自訂義的屬性 |
Number( ) | 把字串或是陣列等轉成數字型別 |
Math.ceil() | 將傳入的數字四捨五入 |
setTimeOut() | 設定一個計時器去執行某個函式或是某片段的程式碼 |
data-target
這個自訂義的屬性,我們之後要利用JS去操控它,這是要讓數字跑起來的第一步 <!-- Twitter-->
<div class="container">
<i class="fa-brands fa-twitter fa-3x"></i>
<div class="counter" data-target="12000"></div>
<span>Twitter Followers</span>
</div>
<!-- Youtube-->
<div class="container">
<i class="fa-brands fa-youtube fa-3x"></i>
<div class="counter" data-target="5000"></div>
<span>Youtube Subscribers</span>
</div>
<!-- Facebook-->
<div class="container">
<i class="fa-brands fa-facebook fa-3x"></i>
<div class="counter" data-target="7500"></div>
<span>Facebook Fans</span>
</div>
* {
box-sizing: border-box;
}
body {
background-color: rgb(116, 66, 116);
color: #fff;
margin: 0;
padding: 0;
display: flex; /*讓內容水平垂直置中*/
justify-content: center;
align-items: center;
height: 100vh;
overflow: hidden;
margin-bottom: 40px;
}
外部容器
.container {
display: flex;
flex-direction: column;
justify-content: center;
text-align: center;
margin: 30px 50px;
}
數字的部分
.counter {
font-size: 60px;
margin-top: 10px;
}
設定中斷點
@media screen and (max-width: 768px) {
body {
flex-direction: column;
}
}
// 取得所有類別為counter的元素
let counters = document.querySelectorAll(".counter");
counters.forEach((counter) => {
let updateCounter = () => {
let target = Number(counter.getAttribute("data-target"));
console.log(typeof target, target);
let c = Number(counter.innerText);
//上面也可寫成 let c =+counter.innerText;
let increment = target / 200;
// 看你想要除多少都可以,除越大的數,每次遞增的量就越少
if (c < target) {
counter.innerText = `${Math.ceil(c + increment)}`;
setTimeout(updateCounter, 1); //單位:ms
} else {
counter.innerText = target;
}
};
updateCounter();
});
getAttribute()
的部分因為會回傳字串,所以我們用Number()
將之轉為數字,你也可以用parsInt()
或是在最前面寫上+
來達成
let c = Number(counter.innerText)
是把目前畫面上的數字存放到c這個變數裡,如果c小於我們的目標數字(變數target)時,它就會每 1 毫秒去執行updateCounter()
這個函式,那當c大於target時,就直接賦予target的值給c
完成圖中的數字會遞增主要是靠updateCounter()
這個函式來達成,而非setTimeOut()
,setTimeOut()
只是讓視覺上有連續的效果,延遲了某段時間 (單位:毫秒) 後,才去執行一次指定的程式碼,其實這邊用setInterval()
重新建構也是可以得到一樣的效果,不過 setInterval() 是延遲了某段時間之後,才去執行對應的程式碼,然後不斷循環,延遲誤差會稍微大一點,關於誤差的部分可以參考這篇文。
附上codepen連結 https://codepen.io/hangineer/pen/rNvmbgM
常常看到有些網頁會有這樣的數字變化效果,這篇跟第五篇 Blurry Loading 模糊加載 有異曲同工之妙,兩個同樣都是在處理延時和定時任務,不過第五篇是使用setInterval
,若有興趣可以去看看
所學不精,若有解說不夠詳盡或是錯誤歡迎指教,感激不盡!那明天見囉
50 Projects In 50 Days - HTML, CSS & JavaScript
setTimeout 與 setInterval
setTimeout()和setInterval() 何时被调用执行