原生JS实现Slider淡入淡出效果

968 阅读1分钟

写在最前面

使用 ES6 的 Class 封装一个 Slider 淡入淡出效果。

主要使用技术和思想

  • Class 类(其实是原型继承的语法糖)
  • setInterval 定时循环,为了优化性能一套循环后 clearInterval 一次
  • 动画过度通过 css3 实现
  • forEach 遍历出来的 node 对象 使用完成后 null 清除
  • 可复用,通过绑定 class='jsFade' 实现

在前端领域还是菜鸟,代码上有任何错误和可以改进的地方,还请各位多多留言指出,非常感激!

HTML

<div class="pc jsFade" data-timer="5000" data-delay="600">
    <img src="images/img1.jpg">
    <img src="images/img2.jpg">
</div>

SCSS

.jsFade{
    position: relative;
    img{
        position: absolute;
        opacity: 0;
        &.active{
            opacity: 1;
        }
    }
}

JS

class JsFade {
    constructor(el, timer, delay) {
        this.el = el;
        this.timer = parseInt(timer) || 3000; // 默认间隔时间
        this.delay = parseInt(delay) || 1000; // 默认动画持续时间
        this.total = this.el.querySelectorAll('img').length;
        this.count = 0;
        this.init();
    }
    init() {
        // 初始化
        this.el.style.height = window.getComputedStyle(
            this.el.querySelector('img')
        ).height;
        this.el.querySelectorAll('img')[0].classList.add('active');
        this.el.querySelectorAll('img').forEach((img) => {
            let _img = img;
            _img.style.transition = `all ${this.delay / 1000}s ease-in`;
            _img = null;
        });

        this.run();
    }
    run() {
        let id = setInterval(() => {
            this.count++;
            // 一套循环后清空优化一次
            if (this.count >= this.total) {
                this.count = 0;
                clearInterval(id);
                this.run();
            }
            this.active(this.count);
        }, this.timer);
    }
    active(id) {
        this.el.querySelectorAll('img').forEach((img) => {
            let _img = img;
            _img.classList.remove('active');
            _img.style.zIndex = 0;
            _img = null;
        });
        this.el.querySelectorAll('img')[id].classList.add('active');
        setTimeout(() => {
            // 动画过度完成后
            this.el.querySelectorAll('img')[id].style.zIndex = 1;
        }, this.delay);
    }
}

if (document.querySelectorAll('.jsFade').length) {
    document.querySelectorAll('.jsFade').forEach((jsFade) => {
        let _jsFade = jsFade;
        let js_fade = new JsFade(
            _jsFade,
            jsFade.getAttribute('data-timer'),
            jsFade.getAttribute('data-delay')
        );
        _jsFade = null; // 清空优化
        js_fade = null; // 清空优化
    });
}

最后

有更好的优化方案,会持续更新的。 谢谢!