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)