挣扎太多的递归

时间:2014-04-06 21:47:30

标签: javascript jquery

Here is my fiddle(警告,由于递归,它会将页面锁定几秒钟)

它基本上会在延迟后更改元素中的文本。

我有几个问题。一个是too much recursion 第二个更多的是与设计有关。如何在不使用init()方法的情况下启动该功能。我宁愿拨打rotate.(["example1", "example2", "example3"]);而不必使用init();

<span id="rotator"></span>

var rotate = {
    quoteIndex: -1,
    duration: 500,
    delay: 3000,
    play: true,
    quotes: [],
    init: function (quotes) {
        this.quotes = quotes;
        this.showNextQuote();
    },
    showNextQuote: function () {
        ++this.quoteIndex;
        $("#rotator").html(this.quotes[this.quoteIndex])
            .fadeIn(this.duration)
            .delay(this.delay)
            .fadeOut(this.duration, this.showNextQuote);
        if (this.play) {
            this.showNextQuote();
        }
    },
    stop: function () {
        this.play = false;
    }



};

var test = rotate.init(["example1", "example2", "example3"]);

3 个答案:

答案 0 :(得分:1)

I updated your fiddle here

递归的主要问题是没有设置停止条件。 此外,您必须知道,当将回调传递给jQuery this时,它会作为dom元素传递,因此您还需要将rotate上下文绑定到它,以便您可以引用this以后没有向你抛出错误。 最后,我假设你想要一个旋转器,所以当递增this.quoteIndex时你必须​​确保它没有超出this.quotes界限所以使用模数来确保一致的结果:1 - &gt ; 2 - &gt; 3 - &gt;再一次等。

var rotate = {
    quoteIndex: -1,
    duration: 500,
    delay: 3000,
    play: true,
    quotes: [],
    init: function (quotes) {
        this.quotes = quotes;
        this.showNextQuote();
    },
    showNextQuote: function () {
        // this is the modulus part that I mentioned above
        this.quoteIndex = (this.quoteIndex + 1) % this.quotes.length;
        // this is our recursion condition which isn't truly recursion in fact
        if (this.play) {
            $("#rotator").html(this.quotes[this.quoteIndex])
                .fadeIn(this.duration)
                .delay(this.delay)
            // bind this to our callback
            .fadeOut(this.duration, this.showNextQuote.bind(this));
        }
    },
    stop: function () {
        this.play = false;
    }



};

var test = rotate.init(["example1", "example2", "example3"]);

答案 1 :(得分:1)

Demo

var rotate = (function(){
    var quoteIndex= -1,
        duration= 500,
        delay= 3000,
        play= true,
        quotes= [],
        $rotator;
    function showNextQuote() {
        ++quoteIndex;
        quoteIndex %= quotes.length;
        $rotator
            .html(quotes[quoteIndex])
            .fadeIn(duration);
        if(play) $rotator
            .delay(delay)
            .fadeOut(duration, showNextQuote);
    }
    function init(q) {
        $rotator = $("#rotator");
        quotes = q;
        showNextQuote();
    }
    init.stop = function() {
        play = false;
    };
    return init;
})();
rotate(["example1", "example2", "example3"]);

答案 2 :(得分:1)

只是对Aduch的回复略有改动。我在立即函数中创建了一个名为rotator的对象,并返回一个在调用时执行init的函数,并返回rotator对象,以便您可以访问stop方法。

var rotate = function(){ // <= wrap object rotator in an immediate function
    // re-wrapped your object 
    var rotator = {
        quoteIndex: -1,
        duration: 500,
        delay: 3000,
        play: true,
        quotes: [],
        init: function (quotes) {
            this.quotes = quotes;
            this.showNextQuote();
        },
        showNextQuote: function () {
            // this is the modulus part that I mentioned above
            this.quoteIndex = (this.quoteIndex + 1) % this.quotes.length;
            // this is our recursion condition which isn't truly recursion in fact
            if (this.play) {
                $("#rotator").html(this.quotes[this.quoteIndex])
                    .fadeIn(this.duration)
                    .delay(this.delay)
                // bind this to our callback
                .fadeOut(this.duration, this.showNextQuote.bind(this));
            }
        },
        stop: function () {
            this.play = false;
        }
    };

    // returning a function so that you execute like you requested.
    return function(ary){
        rotator.init(ary);
        return rotator; // <= returning the rotator so that you can call test.stop()
    };
}(); // <= executes the immediate function

var test = rotate([“example1”,“example2”,“example3”]);