我已經實作了一個計數,它可以根據資料目標進行影片處理。如何調整計數器以便所有計數器同時停止?
或者有沒有更好的方法來實作這一點?
function animationEffect(){
const counters = document.querySelectorAll('.counter');
const speed = 2000;
counters.forEach((counter) => {
const updateCount = () => {
const target = counter.getAttribute('data-target');
const count = counter.innerText;
const inc = target / speed;
if(count < target) {
counter.innerText = Math.ceil(count inc);
setTimeout(updateCount, 1);
} else {
counter.innerText = target;
}
}
updateCount();
});
}
<div class="counter" data-target="299" onmouseover="animationEffect()">0</div>
<div class="counter" data-target="1299" onmouseover="animationEffect()">0</div>
<div class="counter" data-target="99" onmouseover="animationEffect()">0</div>
uj5u.com熱心網友回復:
我不知道它是否有幫助,但是當我更改此行時,它可以正常作業:
const inc = target / speed;
對此:
const inc = 1/(speed / target);
并擺脫 ,Math.ceil()因為這const speed = 2000;實際上是一個步驟創建浮動值。也許嘗試較小的speed值
編輯 多一點調整,我們有一個沒有浮動值的平滑答案>:D
function animationEffect(){
if(animationEffect.called){return null}
animationEffect.called=true
//these 2 lines prevent this function from being called multiple times to prevent overlapping
//the code works without these lines though so remove them if u don't want them
const counters = document.querySelectorAll('.counter');
const incrementConstant = 2; //the higher the number the faster the count rate, the lower the number the slower the count rate
const speed = 2000;
counters.forEach((counter) => {
const updateCount = () => {
const target = counter.getAttribute('data-target');
counter.storedValue=counter.storedValue||counter.innerText-0; //saving a custom value in the element(the floating value)
const count = counter.storedValue; //accessing custom value(and rounding it)
const inc = incrementConstant/(speed / target); //the math thanks to @Tidus
if(count < target) {
counter.storedValue=count inc
counter.innerText = Math.round(counter.storedValue);
setTimeout(updateCount, 1);
} else {
counter.innerText = target;
}
}
updateCount();
});
}
<div class="counter" data-target="299" onmouseover="animationEffect()">0</div>
<div class="counter" data-target="1299" onmouseover="animationEffect()">0</div>
<div class="counter" data-target="99" onmouseover="animationEffect()">0</div>
uj5u.com熱心網友回復:
如果將此代碼粘貼到代碼頂部并運行,當您登錄時,window.activeTimers您將看到定義了數百個計時器。這是因為每次updateCount呼叫時,您都會為 updateCount 設定一個新計時器。盡管您的animationEffect函式就像程式的主要函式,但如果每次我將滑鼠懸停在您的計數器上時都呼叫它,它將設定新的計時器,這意味著每次都更快地更新您的計數器。總而言之,您目前根本無法控制。
對于定期呼叫,您應該使用setInterval。它接受一個函式和一個延遲引數(也有可選的引數。你可以查看檔案)。它repeatedly calls a function or executes a code snippet, with a fixed time delay between each call (From Mozilla docs)。它還回傳一個間隔 ID,以便您以后可以取消它(意味著我們可以控制它)。
因此,在您的情況下,只是為了在所需的時刻停止,您應該做的第一件事就是擺脫對 animationEffect 的滑鼠懸停呼叫,并添加一個按鈕來停止執行 updateCounters。
<div class="counter" data-target="299">0</div>
<div class="counter" data-target="1299">0</div>
<div class="counter" data-target="99">0</div>
<button id="stop">Stop</button>
分配變數后counters,speed我們可以定義一個陣列來保存間隔的 ID,以便稍后取消它們。
const counters = document.querySelectorAll(".counter");
const speed = 2000;
const cancelButton = document.getElementById('stop')
const countIntervals = [];
cancelButton.addEventListener('click', () => {
countIntervals.forEach(interval => clearInterval(interval))
})
如您所見,我為按鈕定義了一個事件偵聽器。當您單擊它時,它將迭代間隔 IDcountIntervals并清除這些間隔。為簡單起見,我沒有實作諸如暫停和重置之類的功能,也沒有嘗試過多更改您的代碼。您可以稍后進行實驗。
現在您應該做的第一件事是setTimeout在 if 陳述句中注釋或洗掉行。然后我們將回傳的間隔 ID 推送到我們的陣列countIntervals:
counters.forEach((counter) => {
const updateCount = () => {
const target = counter.getAttribute("data-target");
const count = counter.innerText;
const inc = target / speed;
if (count < target) {
counter.innerText = Math.ceil(count inc);
// setTimeout(updateCount, 1);
} else {
counter.innerText = target;
}
};
countIntervals.push(setInterval(updateCount, 10))
});
現在,一旦您按下Stop按鈕,您的計數器就會停止。我忽略了速度功能,但如果您了解setInterval您可以輕松實作它。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/378840.html
標籤:javascript 动画片
