前端碼農們在做項目中時候,必定不可少的需要做到輪播效果。但是有些特殊的需求,比如:
需要做到第一個容器內容輪播滾動之后,第二個容器內部再輪播滾動,再第三個容器內容輪播滾動。
這時候我的一開始的思路是:每個容器都看成一個單獨的輪播效果,既然是依次的滾動就設定滾動開始時間差,三個setTimeout()分別延遲差。
HTML 代碼:
< 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 >
CSS 代碼:
.items{height: 18px;overflow: hidden;margin-bottom: 10px;border-bottom: 1px dashed #999;}
JAVASCRIPT 代碼:(基於jquery的實現)
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代碼:
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);
};
這樣就完美解決了這個問題。
我猜想可能由於瀏覽器的特殊性,它的資源有限。所以采用這個策略,也是可以理解的。
