2011-09-08 75 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(這只是我放在一起的樂趣,而不是你的代碼的編輯,所以這是完全不同的。對不起,但希望你還是可以用的東西)