javascript - Vanila JS 柜台
问题描述
试图让所有四个计数器同时完成。例如,计数器 4 应保持为零,直到计数器 3 达到值 14,然后切换到 1。计数器 1 应跟随计数器 2 和 3 递增。
https://jsfiddle.net/IhaveVoicesinMyhead/0j9q1b85/2/#&togetherjs=f3xchiJM9f
const counter = document.querySelectorAll('.counter');
const speed = 200;
counter.forEach(counter => {
const updateCount = () => {
const target = +counter.getAttribute('data-target');
const count = +counter.innerText;
const increment = target / speed;
if (count < target) {
counter.innerText = Math.ceil(count + increment);
setTimeout(updateCount, 80);
} else {
count.innerText = target;
}
}
updateCount();
});
.counters {
margin-top: 2em;
}
.counters .container-max-width {
display: flex;
position: relative;
flex-flow: row nowrap;
justify-content: center;
align-items: stretch;
background-color: #fff;
font-size: 1rem;
text-transform: uppercase;
}
.counters .container-max-width .counter {
font-size: 3.25em;
}
.counters .container-max-width span {
color: #848484;
padding: 0;
}
.counters .container-inner-width {
display: grid;
grid-gap: 200px;
grid-template-columns: repeat(4, 1fr);
padding: 85px 0 85px 0;
text-align: center;
}
<section class="counters">
<div class="container-max-width">
<div class="container-inner-width">
<div>
<div class="counter counter-one" data-target="4">0</div>
<span>counter one</span>
</div>
<div>
<div class="counter counter-two" data-target="10">0</div>
<span>counter two</span>
</div>
<div>
<div class="counter counter-three" data-target="15">0</div>
<span>counter three</span>
</div>
<div>
<div class="counter counter-four" data-target="1">0</div>
<span>counter four</span>
</div>
</div>
</div>
</section>
解决方案
这是一个简单的示例,说明如何创建多个同时结束的计时器。我将其背后的逻辑 (countUp()) 与视图 (createTimer()) 分开,因此您应该能够根据自己的需要调整 countUp() 函数。只需给它您想要的最终值,您希望它执行多长时间(以毫秒为单位),以及您希望它在每个步骤中做什么。
const counter1 = document.getElementById('counter1')
const counter2 = document.getElementById('counter1')
function countUp({ to, onStep, duration, _currentValue = 0 }) {
onStep(_currentValue)
if (_currentValue === to) return
setTimeout(() => {
countUp({ to, onStep,duration, _currentValue: _currentValue + 1 })
}, duration / to)
}
function createTimer(to) {
const timerEl = document.createElement('div')
document.body.appendChild(timerEl)
const onStep = currentValue => {
timerEl.innerText = currentValue
}
countUp({ to, duration: 3000, onStep })
}
createTimer(1)
createTimer(10)
createTimer(20)
请注意,这不考虑 setTimeout() 漂移(setTimeout 并不总是在您要求它时立即执行回调),因此您不应将此解决方案用于更持久或非常精确的计时器。如果你想考虑漂移,你可以添加更多的数学。