多次调用对象时的奇怪行为

时间:2014-04-07 13:25:26

标签: javascript jquery

我这里有一些代码,基本上会从数组中淡入和淡出一些文本。

如果我打电话一次,它按预期工作。 IE,它会显示一些文本3秒钟,并显示数组中下一个文本的淡入淡出。

但是,如果我尝试再次重新启动动画,它似乎运行速度快两倍。谁能帮我?我想我可以正确取消之前的动画

在下面的代码中,我只是为了演示我遇到的问题而致电rotator.start();。只需调用一次,看看它应该如何表现。

http://jsfiddle.net/zmTAC/3/

<div id="foobar"></div>

<script>
    var rotator = {
        quoteIndex: -1,
        duration: 500,
        delay: 3000,
        play: false,
        quotes: [],
        theElement: null,

        start: function (quotes, theElement) {
            this.quoteIndex = -1;
            this.quotes = quotes;
            this.theElement = theElement;
            this.stop();
            this.play = true;
            this.showNextQuote();
            return this;
        },
        showNextQuote: function () {
            this.quoteIndex = (this.quoteIndex + 1) % this.quotes.length;
            if (this.play) {
                $(this.theElement).html(this.quotes[this.quoteIndex])
                    .fadeIn(this.duration)
                    .delay(this.delay)
                    .fadeOut(this.duration, this.showNextQuote.bind(this));
            }
            return this;
        },
        stop: function () {
            this.play = false;
            $(this.theElement).stop(true, true).show();
            return this;
        }
    };

    rotator.start(["foo1", "bar1"], "#foobar");
    rotator.start(["foo2", "bar2"], "#foobar");
    rotator.start(["foo3", "bar3"], "#foobar");
    rotator.start(["foo4", "bar4"], "#foobar");
    rotator.start(["foo5", "bar5"], "#foobar");
    rotator.start(["foo6", "bar6"], "#foobar");
    rotator.start(["foo7", "bar7"], "#foobar");
    rotator.start(["foo8", "bar9"], "#foobar");
    rotator.start(["foo9", "bar9"], "#foobar");
    rotator.start(["foo0", "bar0"], "#foobar");
</script>

3 个答案:

答案 0 :(得分:1)

看起来$.stop()未取消已完成的$.fadeOut()回调。我在最后一次调用中向quotes数组添加了第三个元素,并且每个其他引用都更短(即第二个,然后是第一个(在第二个循环中),然后是第三个,等等。)

我不确定原因是什么(如果它是$.stop()中的错误),但是hack(但它有效)是创建一个容器元素,你在{中强制删除它{1}}和(重新)在rotator.stop()中创建。像这样:

rotator.start()

this fiddle

中查看它

答案 1 :(得分:0)

通过调用start方法,您将覆盖引号。它在foo0bar0之间播放。你想要做的是传递一个单引号数组:

rotator.start(["foo1", "bar1", "foo2", "bar2", "foo3", "bar3"], "#foobar");

对我而言在Firefox和IE上运行良好。 JSFiddle我也改为jQuery 1.11.0,因为1.10在IE上根本不起作用。

修改

我不确定jQuery方面或浏览器方面出了什么问题。我知道你用this.play变量做了一个已知的错误。您将其设置为false,然后设置为true,然后检查它是否为同一功能中的true。如果你同时运行这个函数两次,你会得到:

this.stop(); // second execution is on this line
this.play = true; // first execution is on this line
this.showNextQuote();

可能发生的是第二次执行将this.play设置为false,然后第一次执行将其设置为trueshowNextQuote方法中接下来会执行的操作由两个执行运行,因为this.play trueshowNextQuote,如果this.play为真,则{{1}}函数检查。

我不确定这是不是问题,我很确定这不是问题,但我向您展示的是当您尝试运行多个异步操作时会发生什么。我很确定它是有缺陷的jQuery。也许更新的版本修复了这个?

也许其他社区成员对此有更多话要说?

Solution

<强> EDIT2

考虑到它,JS不会允许它发生,因为它不会在单独的线程中执行此代码。我不会删除它,因为它解释了你使用可能导致你的问题的异步jQuery犯这个错误是多么容易。

答案 2 :(得分:0)

你可以尝试这个而不是你的停止方法中的注释行

//$(this.theElement).stop(true, true).show();
$(this.theElement).finish().show();

工作示例here