javascript - 错误算法触发并发循环

时间:2011-09-08 03:48:52

标签: javascript prototypejs delay mouseout banner

我创建了一个相对较小的动态横幅旋转脚本,底部带有图标,用于关注特定横幅。在横幅上放置鼠标中心会暂停显示,但有时当我从横幅中鼠标拖出时,某些横幅的延迟会缩短。我甚至不知道它是否只发生过一次,但是每次横幅在旋转中回来时,延迟时间设置为较短的时间,并且通常缩短发生在横幅列表中的另一个地方,如好。有时这可以通过尚未确定的一组动作来纠正。我开始怀疑我的逻辑是在中间的某个地方捕获循环,因此进程分支出来,运行两个循环,这似乎加快了showNextBanner函数的调用。不知道如何解决这个问题。我已经进行了测试,看看它目前是否处于播放模式,但无济于事。

我包含了我认为下面代码的相关部分。

        var firstRun = true;
        var play = true;
        var current = 0;

        var banners = $$( '.banner' ); 
        banners.invoke( 'hide' );
        var images = $$( '.image' );
        var icons = $$( '.icon' );
        //dynamically clones an initial icon to match the number of banners
        initIcons();

        banners.invoke( 'observe', 'mouseenter', function( field ) {
            play = false;
        });

        banners.invoke( 'observe', 'mouseleave', function( field ) {
            if( !play ) {
                play = true;
                showNextBanner().delay(3);
            }
        });

        icons.invoke( 'observe', 'click', function( field ) {
                play = false;
                hideBanner( current );
                showBanner( findObj( icons, field.findElement()));
        });


        showNextBanner().delay(3); 


        function hideBanner( which ) {
            icons[ which ].src = blankIconSRC;
            banners[ which ].hide();
        }


        function showBanner( which ) {
            icons[ which ].src = selectedIconSRC;
            banners[ which ].show();
            current = which;
        }


        // loops the hiding and showing of icons 
        // (mouseenter sets play to false)
        function showNextBanner() {
            if( play ) {
                if( !firstRun ) {
                    if( ++current == banners.length ) current = 0;    
                    var previous = 0;
                    ( current == 0 )? previous = banners.length - 1: previous = current - 1;
                    hideBanner( previous );
                } else {
                    icons[0].src = selectedIconSRC;
                    firstRun = false;
                }
                showBanner( current );
                showNextBanner.delay(3);
            }
        }
    }());

毕竟,客户想要一个jQuery解决方案,这样他就可以通过scriptaculous获得滑入效果。所有这些工作都耗尽了。好消息是我可以使用jCarousel,并调整样式表。谢谢你的帮助!

2 个答案:

答案 0 :(得分:0)

我怀疑发生的事情是你有多个.delay调用堆叠起来。所以你剩下的时间不到3秒,再次调用showNextBanner,设置另一个延迟计时器。

当我阅读文档时,看起来.delay旨在在jquery事件管道中添加空白,而不是实际延迟函数调用。您可以通过切换到调用setTimeout而不是延迟来获益,这样您就可以获得超时的句柄,然后可以在设置新的超时之前取消(如果播放设置为false则取消,然后在播放为真时重置)这在JQuery docs for .delay

中提到

答案 1 :(得分:0)

我的猜测是,由于你没有“取消”delay()'ed函数,它们会挂起太长时间,但是当它们触发时它们什么都不做,因为play是假。但是一旦再次播放true,所有人都会再次开始效果。

您可以保存delay()的返回值,并使用值clearTimeout()取消计时器。

但是,我还建议您为所有横幅使用单个容器(也可以将图标放在那里),并在其上设置mouseenter / mouseleave个事件,而不是单独的横幅。然后只有一个元素可以启动/停止横幅旋转。如果您还在播放和停止旋转的特定功能中拆分所有内容,并且显示特定横幅,则可以获得更清晰的代码结构。

Here's an example(这只是我为了好玩而放在一起而不是编辑你的代码的东西,所以它完全不同。抱歉。但希望你仍然可以使用某些东西)