javascript 滚动计数器递增1

tp5buhyn  于 11个月前  发布在  Java
关注(0)|答案(2)|浏览(88)

我需要对计数器的脚本帮助,以增加一个,并有一个递增的数字动画,幻灯片到顶部


的数据
就像照片上的那样,这就是我到目前为止所做的。

.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;
    }

个字符

1tu0hz3e

1tu0hz3e1#

你可能应该使用一些现有的库。但是如果你想有自己的实现,那么使用以下元素:

  • 使用CSS transitions,特别是transition属性和transitionend事件。
  • 动态构建内部HTML,这样在原始HTML中就只有容器元素,它最初是空的。
  • 让HTML在最深的层次(对于一个数字)是3行:在每行上放置一个数字。例如8<br>9<br>0。它们应该形成一个序列。将中间的数字滚动到视图中,以便只有该数字可见。根据需要向上或向下执行动画,当动画完成时,更新HTML并重置滚动偏移量(可以是top CSS属性)。
  • 不需要span元素。只需将内容直接放入li元素中。
  • 使用promise,它使异步代码看起来更好,尤其是在使用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.style.transition = `${prop} 0ms`;
            resolve();
        }
        elem.addEventListener("transitionend", done, {once: true});
    })).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;
    border-left: 1px solid black;
    position: relative;
    top: 0;
}
.order-list > li:first-child {
    border-left: 0;
}
<ul id="order-list" class="order-list"></ul>

有一些参数可以用来修改动画的速度,还有一个参数可以决定拨号盘是向上滚动还是向下滚动以获得下一个数字。

7qhs6swi

7qhs6swi2#

只需使用odometerjs,这是一个JavaScript库,用于添加具有各种主题的滚动计数器。
https://github.hubspot.com/odometer/docs/welcome/

相关问题