无限期地重复一个函数,最好不要使用setInterval()

时间:2016-11-02 21:47:45

标签: javascript jquery loops

我正在构建一个幻灯片放映框架,并且无法找出循环动画功能的最佳方法,我知道我可以使用setInterval()但是想知道是否有更好的方法来重复它而不是资源密集型。

JAVASCRIPT:

class slideShow {
    constructor(imgDir, dataList) {
        this.imgDir = imgDir;
        this.dataList = dataList;
        this.settings = 0;
        this.imgList = 0;
        this._init();
    }
    _init(){
        $.getJSON(`${this.imgDir}/${this.dataList}.json`, (data)=>{
            this.settings = data.settings;
            this.imgList = data.imgList;
        })
    }
    start(){
        for(let img of this.imgList){
            $(this.settings.selector).fadeOut(this.settings.fadeTime, ()=>{
                $(this.settings.selector).attr("src",`${this.imgDir}/${img}`);
                $(this.settings.selector).fadeIn(this.settings.fadeTime);
            });
        }
    }
}

JSON:

{
    "settings":{
        "selector":"#slideShow",
        "fadeTime":1000
    },
    "imgList":[
        "slide_01.jpg",
        "slide_02.jpg",
        "slide_03.jpg"
    ]
}

2 个答案:

答案 0 :(得分:2)

一个简单的解决方案是从"完成回调"伪递归循环。动画的最后一步。

WITH

请注意,我已删除了Signal循环 - start() { var current = 0; (function loop() { let img = imgList[current++]; current %= imgList.length; let $sel = $(this.settings.selector); $sel.fadeOut(this.settings.fadeTime, () => { $sel.attr("src",`${this.imgDir}/${img}`); $sel.fadeIn(this.settings.fadeTime, loop); // <-- here }); })(); } 函数的每次传递都只处理幻灯片的一帧。

这可以解决原始代码中的错误,您可以在其中获得三个连续的for ... of动画(其中两个当然是不可见的),因为您的代码中没有任何内容允许loop的第一个循环在fadeOut循环的下一次迭代开始之前完成。

答案 1 :(得分:1)

您可以使用.then(),jQuery .promise(),递归

class slideShow {
    constructor(imgDir, dataList) {
        this.imgDir = imgDir;
        this.dataList = dataList;
        this.settings = 0;
        this.imgList = 0;
        this._init();
    }
    _init(){
        $.getJSON(`${this.imgDir}/${this.dataList}.json`, (data)=>{
            this.settings = data.settings;
            this.imgList = data.imgList;
        }).then(this.start)
    }
    start(){
        for(let img of this.imgList){
            $(this.settings.selector).fadeOut(this.settings.fadeTime, ()=>{
                $(this.settings.selector).attr("src",`${this.imgDir}/${img}`);
                $(this.settings.selector).fadeIn(this.settings.fadeTime);
            });
        }
        $(this.settings.selector).promise()
        .then(() => this.start() /* or this._init() */)
    }
}