2011-09-08 48 views
0

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

我包括我认为是下面的代码的相关部分。

 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,并且可以调整样式表。谢谢您的帮助!

+0

'showNextBanner'不返回任何如此'showNextBanner()。delay(3)'可能会导致错误。浏览器容忍这样的事情,所以它可能会继续,但我不希望有那种多余的延迟。 – clockworkgeek

回答

0

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

当我阅读文档时,它显示.delay旨在填补jquery事件管道中的空白,而不是实际上延迟函数调用。您可以切换到调用setTimeout而不是延迟,以便获取超时的句柄,然后可以在设置新的超时之前取消超时(或者,如果play设置为false,则取消;如果play is true,则重置)这是中提到的JQuery docs for .delay

+0

您的怀疑无疑是正确的,但它实际上是[Prototype.js](http://www.prototypejs.org/),而不是jQuery,正在使用它。但是这两个库都有一个'delay()'函数,所以你需要[这些文档](http://api.prototypejs.org/language/Function/prototype/delay/) – Flambino

0

我的猜测是因为你不“取消”的delay()“版的功能,他们流连太久,但他们不这样做,当他们解雇任何事情,因为play是假的。但是一旦再次玩true,全部开始有效。

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

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

Here's an example(这只是我放在一起的乐趣,而不是你的代码的编辑,所以这是完全不同的。对不起,但希望你还是可以用的东西)