六月ovo
2017-03-26 00:48
照着视频的代码实践了一次,发现没有把flag重置为true的代码,但是最后确确实实是清除了定时器,那么,flag是什么时候被重置的呢?
另外,看到有人回答,flag应该被声明在定时器里面,这个是不对的。如果声明在定时器里面,那么就会出现视频中声明flag之前的bug。
求大神解答一下。
上面的问题好像有点不清晰哈,下面说清楚一点。
flag=true是放在定时器外面的,对吧?定时器里面是没有代码把flag重置为true的,当第一次代码执行到
if(icur!=json[attr]){ flag=false; }
这里的时候,flag就被赋值为false了,之后都没有给flag赋值为true。
那么最后是怎么判断到flag=true的呢?
在这里就很不明白,因为没有把flag重置为true的话,其实是没办法执行
if(flag){ clearInterval(obj.timer); if(fn){ fn(); } }
和之后的fn函数的。
看完了楼主写的,完全没有毛病,教程代码确实有BUG,不过既然因为 speed = (json[attr] - icur)/8 语句, 当 speed 为0时就能自己停止,为什么教程还要加一大堆检测停止的代码,我发现把那一大段去掉之后功能正常啊,不知道我有没有想错?
把flag放外面,最后速度为0,动画是停止了,但是代码一直在运行,无限循环的运行,if(flag)永远到不了
没仔细看,原来你的代码已经解决了。。
一、var flag = true; 是放在定时器外面的。
二、每次启动定时器强制 flag = true。
三、在for循环外面,再次判断flag。
还需要把
if(flag){
clearInterval(obj.timer);
if(fn){
fn();
}
这一段放在for 循环外面。。.
-------------手动分割------------------
楼主,你看看有木有bug,或者你有其他解决方案了没有?
我去,不行。。
//同步运动函数 function move(obj, json, fn) { //清除定时器,避免出现多个定时器 clearInterval(obj.timer); //设定定时器 obj.timer = setInterval(function () { //声明标杆 var flag = true; //遍历同步运动属性 for (var attr in json) { //获取属性值 var icur = 0; if (attr == 'opacity') { icur = Math.round(parseFloat(getStyle(obj,attr)) * 100); } else { icur = parseInt(getStyle(obj, attr)); } //设置运动速度 var speed = (json[attr] - icur)/100; speed = speed>0?Math.ceil(speed):Math.floor(speed); // 判断是否所有值都达到了目标值,判定暂停定时器的指标 if (icur != json[attr]) { flag = false; } if (attr == 'opacity') { obj.style.opacity = (icur + speed) / 100; obj.style.filter = 'alpha(opacity:' + (icur + speed) + ')'; } else { obj.style[attr] = (icur + speed) + 'px'; } } // 注意,for in遍历到此结束,下面的清除定时器部分不属于for遍历里面的代码,是定时器最后面的部分 //清除定时器 if(flag){ clearInterval(obj.timer); if(fn){ fn(); } } }, 1); } //获取任意属性 function getStyle(obj, attr) { if (obj.currentStyle) { return obj.currentStyle[attr]; //IE取样式 } else { return getComputedStyle(obj, false)[attr]; } }
经过多番测试,视频中的完美运动代码存在bug,这个框架只可以实现同步动画,不可以实现链式动画。
同步动画最后会停止,不是因为
if(flag){ clearInterval(obj.timer); if(fn){ fn(); } }
而是代码中的
speed = (json[attr] - icur)/8;
这一部分等于0了,也就是说,动画不再变化了,看起来就好像清除了定时器一样。
如果在清除定时器的判定语句中加入一个测试语句,可以发现,第一次鼠标移入目标的时候,第一次执行到这个动画,是不会执行到测试的语句的,说明定时器的判定语句并未执行。
if(flag){ alert(12345678978979); //注意这部分,第一次执行动画的时候,是不会执行到这里的。因为flag一直是false clearInterval(obj.timer); if(fn){ fn(); } }
如果没有onmouseout的动画,那么,第二次鼠标移进去的时候,在执行动画之前,都满足
json[attr]=icur;
也就是说speed在第二次执行动画的时候,一直是0,那么这个时候,下面这个判定就没有执行了
if(icur != json[attr]){ flag = false; }
于是flag就是第二次执行动画的初始值,也就是:
var flag = true;
自然而然的,后面的这部分代码就能够执行了。
if(flag){ alert(12345678978979);//第二次执行onmouseover动画,就会执行到这里了 clearInterval(obj.timer); if(fn){ fn(); } }
上面讲得比较啰嗦,不知道大家有没有看懂,没看懂的可以照着一步一步去尝试一下,会得到我说的这个结果的
首先我终于找到跟我一样认为flag是放在定时器外的人了,这一节课里面用的json[attr]不是target,json[attr]就相当于json.attr; 源码:
if(itur != json[attr] ){ flag=false; }
我资质较浅,我以个人名义说说我的想法,
var flag=true;这是放在计时器外的对吧,当遇到if(itur != json[attr] )语句的时候,就把flag这个全局变量设为false, 如果if(itur != json[attr] )不成立的时候,if( flag ){}这个语句就会找到全局变量,所以这就是为什么要放在计时器外
评论在一楼的那位大哥已经误导了大家,flag放在计时器内会出现bug.
你的问题我有点看不明白啊哥们,说的明白些
。。。。。好像看错问题,你忽略我的回答吧
当最后一个目标完成后,因为setInterval,会重新初始化flag为true
JS动画效果
113925 学习 · 1443 问题
相似问题