javascript的setTimeout以及setInterval休眠問題。
需要做到第一個容器內容輪播滾動之後,第二個容器內部再輪播滾動,再第三個容器內容輪播滾動。 這時候我的一開始的思路是:每個容器都看成一個單獨的輪播效果,既然是依次的滾動就設定滾動開始時間差,三個setTimeout()分別延遲差。 HTML 程式碼: 複製代碼<div id="warp"> <div class="items"> <ul class="island s1"> <li>111</li> <li>222</li> <li>333</li> </ul> </div> <div class="items"> <ul class="island s2"> <li>444</li> <li>555</li> <li>666</li> </ul> </div> <div class="items"> <ul class="island s3"> <li>777</li> <li>888</li> <li>999</li> <li>000</li> </ul> </div> </div> 複製代碼 CSS 代碼: .items{height: 18px;overflow: hidden;margin-bottom: 10px;border-bottom: 1px dashed #999;} JAVASCRIPT 代碼:(基於jquery的實現) 複製代碼var uls = $("#warp").find(".island"), lh = uls.find('li').height(), size = uls.size(), Global=[];//全域變數 uls.each(function(i,el){ $(el).find('li').first().clone(true).appendTo($(el)); }); /*動畫效果*/function animates(i){ Global[i]==undefined&&(Global[i]=0); Global[i]++; _els =uls.eq(i); var len = _els.find('li').length; _els.animate({"marginTop":-Global[i]*lh+"px"},600,function(){ if(Global[i] == len-1){ Global[i]=0; _els.css({"margin-top":"0px"}); } }); };function interval(i){ setInterval(function(){ animates(i) },5000);};for(var x=0;x<size;x++){ (function(x){ setTimeout(function(){ interval(x); },650+x*650); })(x)}; 複製代碼一開始的時候我發現都是OK的,但是當我切換到別的頁面,或者暫時最小化的時候,輪播就變得雜亂無章。這個問題困擾我很久,到公司請教 大牛同事,他說可能是 setInterval休眠問題導致。 經過仔細的查閱資料以及實踐,發現當頁面最小化時候或者切換網頁瀏覽其他網頁等情況時, setInterval是會暫時進入“休眠”狀態,但是並不是不執行程式,它會把需要執行的操作放在隊列中 ,等到下次視窗一開啟的一瞬間把隊列裡面的全部執行,由於程式處理太快我們大部分時候並沒有注意到這個問題。但是你去看所有網站的輪播效果, 假設現在你輪播的是第四張大圖,下次開啟時候播放的可能是任意的。 再分析上面的程式: 我們讓程式分別過650ms, 1300ms,1950ms執行如果視窗一直是這個是本視窗,也就是沒有進行休眠。程式可以照常執行。 如果視窗最小化,程式進入休眠,會把隊列中的操作在很快時間內一起執行,所以程式一下子就亂啦。 那如何解決這個問題呢?還是想了啦jquery的animate,如果在動畫animate的回調中進行遞迴,進入下次的輪播。那不就完美解決!! 讓我們來看程式: JAVASCRIPT代碼: 複製代碼var uls = $("#warp").find(".island"), lh = uls.find('li').height(), size = uls.size(), i = 0; uls.each(function(i,el){ $(el).find('li').first().clone(true).appendTo($(el));});function animates(i){ var ul = $('.items').eq(i).find('ul'); if(!ul){return false;} var count = parseInt(ul.attr("count-role")||0); count++; var len = ul.find('li').length; ul.animate({"marginTop":-count*lh+"px"},600,function(){ if(count == len-1){ count=0; ul.css({"margin-top":"0px"}); } ul.attr("count-role",count); animates(++i); }); };function interval(){ setInterval(function(){ animates(i) },5000);};interval() 複製代碼這樣就完美解決了這個問題。 我猜想可能由於瀏覽器的特殊性,它的資源有限。所以採用這個策略,也是可以理解的。