我需要有关脚本的帮助,以使计数器递增1,并获得递增数字的动画,滑至顶部
类似的东西上的照片,这是我迄今所做的。
.booking-wrapper .countdown-wrapper .countdown-container .order-list {
border: 5px solid #959595;
list-style-type: none;
padding-left: 0;
margin-bottom: 0;
overflow: hidden;
line-height: 1;
height: 56px;
margin-top: 8px;
}
.booking-wrapper .countdown-wrapper .countdown-container .order-list .order-list-item {
display: inline;
font-size: 40px;
font-weight: bold;
padding: 0 15px;
}
<div class="countdown-container">
<ul id="order-list" class="order-list">
<li class="order-list-item"><span>0</span></li>
<li class="order-list-item" style="border-left: 1px solid black;"><span>0</span></li>
<li class="order-list-item" style="border-left: 1px solid black; border-right: 1px solid black;"><span>8</span></li>
<li class="order-list-item"><span>1</span></li>
</ul>
</div>
答案 0 :(得分:0)
您可能应该为此使用一些现有的库。但是,如果您想拥有自己的实现,请使用以下元素:
transition
属性和transitionend
事件。8<br>9<br>0
。它们应该形成一个序列。将中间数字滚动到视图中,以便仅可见该数字。根据需要向上或向下执行动画,动画完成后,更新HTML并重置滚动偏移量(可以是top
CSS属性)。span
元素。只需将内容直接放入li
元素中即可。await
这就是您的操作方法:
// Utility functions returning promises
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
const nextFrame = () => new Promise(resolve => requestAnimationFrame(resolve));
const animate = (elem, prop, value, duration) => {
return nextFrame().then(() => new Promise(resolve => {
elem.style.transition = `${prop} ${duration}ms`;
elem.style[prop] = `${value}px`;
const done = () => {
elem.removeEventListener("transitionend", done);
elem.style.transition = `${prop} 0ms`;
resolve();
}
elem.addEventListener("transitionend", done);
})).then(nextFrame);
};
// DOM element wrapper for the counter functionality
class Counter {
constructor(element, length = 4, upwards = true) {
this.element = element;
this._value = 0;
this.upwards = !!upwards;
this.digits = Array.from({length}, () => element.appendChild(document.createElement("li")));
}
get value() {
return this._value;
}
set value(value) {
this._value = value;
const numStr = value.toString().padStart(4, "0").slice(-this.digits.length);
// Display the current number in the counter element (no animation)
this.digits.forEach( (digit, i) => {
// Put three lines, each having a digit, where the middle one is the current one:
digit.innerHTML = `${(+numStr[i]+(this.upwards ? 9 : 1))%10}<br>${numStr[i]}<br>${(+numStr[i]+(this.upwards ? 1 : 9))%10}`;
digit.style.top = `${-this.element.clientHeight}px`; // scroll the middle digit into view
});
}
async roll(direction = 1, duration = 500) {
await nextFrame();
const numChangingDigits = Math.min(this.digits.length,
this.value.toString().length - this.value.toString().search(direction > 0 ? /9*$/ : /0*$/) + 1);
const numStr = this.value.toString().padStart(4, "0").slice(-numChangingDigits);
const promises = this.digits.slice(-numChangingDigits).map((digit, i) =>
animate(digit, "top", (direction > 0) === this.upwards ? -this.element.clientHeight*2 : 0, duration)
);
await Promise.all(promises);
this.value = this.value + direction;
await nextFrame();
}
async rollTo(target, duration = 500, pause = 300) {
const direction = Math.sign(target - this.value);
while (this.value !== target) {
await this.roll(direction, duration);
await delay(pause);
}
}
}
// Demo:
const counter = new Counter(document.getElementById("order-list"), 4, true);
counter.value = 9931;
counter.rollTo(10002, 500, 300);
.order-list {
border: 5px solid #999;
list-style-type: none;
padding-left: 0;
overflow: hidden;
height: 50px;
line-height: 1;
display: inline-block;
}
.order-list > li {
display: inline-block;
font-size: 50px;
font-weight: bold;
padding: 0 15px;
outline: 1px solid black;
position: relative;
top: 0;
}
<ul id="order-list" class="order-list"></ul>
您可以使用一些参数来修改动画的速度。还有一个参数可以确定拨盘是向上滚动还是向下滚动以获取下一个数字。