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() 

這樣就完美解決了這個問題。

我猜想可能由於瀏覽器的特殊性,它的資源有限。所以采用這個策略,也是可以理解的。

 

 

 

 

 

 



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM