视频10:53处有解决方法
代码是存在问题,但错不在这,
var flag = true; 需要定义在定时器内
function commonStartMove(obj, json, fun) {
clearInterval(obj.timer);
obj.timer = setInterval(function () {
var flag = true; // 需要将flag定义在此处 ?
for (var attr in json) {
...
}
if (flag) {
clearInterval(obj.timer);
if (fun) {
fun();
}
}
}, 30);
}
按自己的理解改了部分代码 :)
视频中flag的声明位置应该是写错了,实际上应该是写在定时器内。
视频中为什么动画会停止?完全是因为speed归0了,动画停止了,但实际上定时器并没有停止,还在继续运行。
感谢 @纸丶两面白 同学!
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> body { margin: 0px; } li { width:200px; height:50px; list-style-type:none; margin-bottom:10px; background-color:brown; filter:alpha(opacity=30); opacity:0.3; } </style> <script type="text/javascript"> window.onload = function(){ var li = document.getElementsByTagName('li'); for(var i=0;i<li.length;i++){ li[i].timer=null; li[i].onmouseover = function(){ startMove(this,{'width':400},function(obj){//这里的obj参数由startMobe方法调用回调那里传回来,方便解决这行的函数找不到对象的问题 startMove(obj,{'height':300,'opacity':100});//用了json同时实现高和透明度的修改 }); } //鼠标移开 li[i].onmouseout = function(){ startMove(this,{'width':200,'height':50,'opacity':30});//用了json同时实现宽高透明度的修改 } } } var alpha=30; function startMove(obj,json,fn){ clearInterval(obj.timer); var curStyle=0; obj.timer = setInterval(function(){ var flag=true;//flag如果放在外面的话在计时器里面被修改之后就不会再变回true的值了,如果在计时器里面,每次计时都会把flag重新赋值true for(var attr in json){ curStyle=(attr=='opacity')?Math.round(parseFloat(getStyle(obj,attr))*100):parseInt(getStyle(obj,attr));//这里把if(){}else{}的判断是不是opacity写成一句了 var speed = (json[attr]-curStyle)/10; speed = (attr=='opacity')?speed:(speed>0?Math.ceil(speed):Math.floor(speed)); if(curStyle!=json[attr]){//如果不能同时满足所有当前的属性值等于目标值就给flag赋值false flag=false; } obj.style[attr]=(attr=='opacity')?(curStyle+speed)/100:(curStyle+speed+'px'); if(flag){ clearInterval(obj.timer); if(fn){ fn(obj);//这里把obj做成参数主要是方便处理回调函数fn的对象问题 } } } },30) } function getStyle(obj,attr){ if(obj.currentStyle){ return obj.currentStyle[attr]; }else{ return window.getComputedStyle(obj,false)[attr]; } } </script> </head> <body> <li id="li"></li> <li></li> <li></li> <li></li> <li></li> <li></li> </body> </html>
--------------------------------------------------------------------------------------
花了大半天写好的,不知道有没有你想要的“第二个属性和第三个属性继续同步完成”
朋友,谁说同时运动不可以有链式运动呀,比如说你要把 width 和 height 同时运动完成了,再运动透明度opacity。那这时,你不就是需要链式运动了吗。
PS最后这位大神姐姐这一课都标明了,是更好的运动框架,
既可以同时运动,也可以链式运动,你要什么情况你就码什么代码就可以了
修改后的代码:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> <style type="text/css"> *{margin: 0; padding: 0;} ul,li{list-style: none;} ul li{width:200px;height:100px;background:yellow;opacity:0.3;filter:alpha(opacity:30);border: #ccc 4px solid;} </style> </head> <script type="text/javascript" > function startMove(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)); } //speed var iSpeed = (json[attr] - iCur) / 8; iSpeed = iSpeed>0?Math.ceil(iSpeed):Math.floor(iSpeed); //stop if(iCur != json[attr]) { flag = false; } if(attr == 'opacity') { obj.style.filter = 'alpha(opacity:'+ (iCur + iSpeed) +')'; obj.style.opacity = (iCur + iSpeed) / 100; } else { obj.style[attr] = iCur + iSpeed + 'px'; } } if(flag){ clearInterval(obj.timer); if(fn){ fn(); } } }, 30) } function getStyle(obj, attr) { if(obj.currentStyle) { return obj.currentStyle[attr]; } else { return getComputedStyle(obj, false)[attr]; } } </script> <script> window.onload = function(){ var oLi=document.getElementById('li1'); oLi.onmouseover = function(){ startMove(oLi,{width:400,height:200,opacity:100}); } oLi.onmouseout = function(){ startMove(oLi,{width:200,height:100,opacity:30}); } } </script> <body> <ul> <li id="li1"></li> </ul> </body> </html>
视频中flag的声明位置应该是写错了,实际上应该是写在定时器内。
视频中为什么动画会停止?完全是因为speed归0了,动画停止了,但实际上定时器并没有停止,还在继续运行。
视频中flag的声明位置应该是写错了,实际上应该是写在定时器内。
视频中为什么动画会停止?完全是因为speed归0了,动画停止了,但实际上定时器并没有停止,还在继续运行。
else {
icur = Math.round(parseFloat(getStyle(obj, attr)));
}
这句错了,应该是
else {
icur = parseInt(getStyle(obj, attr)); //整数型
}
要是缓冲运动就不需要flag
终于想通了,还是flag的问题。大家注意,var flag =true;这句话一定一定要放在for-in外面
理解如下:
首先for-in虽然使得看起来是同步进行,但实际还是你定义的运动1,运动2,运动3 顺序操作。
当放在外面的时候,三个运动是修改一个flag,有一个没满足都是false。
而当flag定义放在循环里的时候,每一个运动的每一次操作,都会重置flag为true。
模拟一下:
假定速度为1.
首先第一圈。宽是false,然运动,达到目标。高是false,运动,仍未达到。透明度是false,运动,仍未达到。
第二圈,宽为true,无运动,高是false,运动,仍未达到。透明度是false,运动,仍未达到。
第N-1圈,高值196,false, =197 ,透明度值0.31 false = 0.3
第N圈,高值为197,判断为false之后,高变成198 。而因为在刚刚N-1圈的时候,透明度的运动刚好达到目标值。所以这一圈初始就把运动2判断为false的flag掰成了true。
清除定时器。BUG出现。这也是为什么速度值改变结果会不一样。
总结:如果flag定义放在for-in。则你定义的3个运动里如果某个运动时间大于 排序靠后的,则这个运动无法完成。除非,你的速度够快。
没有attr呀~ 你代码里的 应该把attr改为i,for循环里 json的属性名。
新手哈
不是应该第一个循环结束后,执行第二个吗?按理说应该是顺序啊!
仔细检查检查
getComputedStyle( obj )[attr]; }需要flase,getComputedStyle要两个参数
你说的animate是指直接调用这个方法,主要传参就行了吗?
script标签不能写在<style></style>之间,而且函数名是startMove,调用的时候写出startMove1
有的这是vivian老师的主页
http://www.imooc.com/u/100329/courses?sort=publish
你可以在里面查看她的所有课程
运动框架引用啊,
``搞定了`` 一脸懵逼
不好意思,我已经找出来了,本人在for( var attr in json){}中把 attr 写成 i了,所以浏览器识别不了。
测试了一下可以用,看看是不是JS<script src="move.js"></script>引用路径有误,另外需要加Flag来保证只有每个值都达到target才停止动画,不然透明度到1宽度还没到400就不动了
把flag定义在定时器里,for循环外。评论里第一说了,你可以看下
startMove{this,opacity:100,width:300}
这是因为你要确定你设置的多运动都完成后才去清除定时器,这个flag就是用来判断你设置的所有运动,比如高度宽度透明度是否都达到了目标值,flag才为true,否则之前flag会变成flase,不执行清除定时器