For循環線程與JQ動畫結合的問題
前言:
最近做了一組數字翻滾動畫,期間采用jq的animate動畫和for循環,對拼接成數組的數字進行展示,踩了不少坑,在此做個記錄,將心得整理一下。
序:貼代碼如下(寫個序,其實就是為了貼代碼,哈哈,我太邪惡了):
Html:
<div class="cont">
<div class="box">
</div>
<button type="button" onclick="$.fn.move()">點擊翻滾</button>
</div>
Js:
// animate
$.fn.move = function(){
var arr = numAdd();
console.log(arr)
for(var i=0;i<$('.num').not('.comma').length+1;i++){
for(var j=0;j<10;j++){
if(arr[i] == $(".num>div>div").eq(j).text()){
var value = -68*j + 'px';
var hei = $(".num>div").eq(i).css("top");
var newTop = -68*j,oldTop = parseFloat(hei.split("px")[0]);
if(newTop < oldTop){
$(".num>div").eq(i).animate({top:value},800);
}else if(newTop > oldTop){
var topNew = -68*(j+10)+'px';
$(".num>div").eq(i).append($(domNum).addClass('temp'));
console.log('newTop['+j+']=='+ newTop + '---oldTop[' + i + ']--'+ oldTop + '---value=='+value)
$(".num>div").eq(i).animate({top:topNew},500)
console.log(value)
$(".num>div").eq(i).animate({top:value},10);
setTimeout(function(){
$(".num>div>.temp").remove();
},800)
}else{
$(".num>div").eq(i).animate({top:value},800);
}
}
}
}
}
Css這塊就不貼了,期間對于數字的翻滾用到了絕對定位。
坑的解析:
1、move函數中for循環的雙層嵌套,執行過程的時間是短暫的,而且每一次執行當中啟動的animate都帶有延時加載的特性,可視為單個線程的運行互不影響,
2、Animate的運行,在延時結束的時間,我們需要去進行多余dom的清除和第一組數據對應值的歸位(稱為回歸,比如說原來的數字某一位是6,要變更為3;我們需要從6開始上滾到展示9,在從0開始滾到到展示3;之后便是回歸的開始,將dom的css定位到第組0-9中的3的位置展示,并刪除第二組0-9的dom),而回歸的開始時間,for循環已經執行結束,拋出最大的i值;
(the importent最重要的問題 ,循環內animate執行結束之前,for循環已經執行結束)
3、因此,此時回歸的value值,取的i就是最大的i,對應每一個.num內歸位的情況就是,全部都變成了最大的value值;
解決辦法:
在循環中animate執行的下一步,添加一次性定時器(相當于另起一個線程,讓沒一次for循環中都啟動兩個互不影響的線程,在延遲時間之后再執行另一個線程),這個線程定時在animate執行完畢之后再開始執行,此時不影響animate的變化效果,并完美解決了for循環的執行與animate延時線程之間無法歸位和滾動錯亂的問題。
寫法如下:
$(namet).eq(i).animate({top:topNew},800)
$(namet).eq(i).animate({top:value},10);
setTimeout(function(){
$(".num>div>.temp").remove();
},900)