为了账号安全,请及时绑定邮箱和手机立即绑定

关于完美运动框架小bug的修复,附源码

自己写了一遍完美框架,发现很多重要的小细节(主要还是变量声明的位置问题,即什么时候声明)。然后,看了楼下 @赫克托耳 同学的评论,说一下关于他提出的问题3:【无法执行回调函数的解决方法 】

1、我先用控制台在每次for-in循环的结尾输出了flag的值。发现,flag变为false后,没有使其变成true的触发语句啊(不知道老师为什么能执行,疑问)

2、也想过 @赫克托耳 同学提到的 if(json[attr] != curStyle){flag= false;}else{flag=true;} 这种。但这种肯定不对 

3、于是想到在每次时间间隔开始置flag为true,

     回调函数这一问题的解决方法,就是下面代码的第6行。

    源码给大家了,大家最好自己敲一遍哦,反正我自己在敲得时候有太多问题了。

// 完美运动框架
function startMove(obj,json,fn){
	var flag = true;
	clearInterval(obj.timer);
	obj.timer = setInterval(function(){
			flag = true;//    亲们,就是这一句啊,重要的一句啊
			var speed = 0,
				icur = null;
			for(var attr in json)
			{
				//	判断速度
				if(attr == "opacity"){
					icur = Math.round(parseFloat(getStyle(obj,attr))*100);
				}else{
					icur = parseInt(getStyle(obj,attr));
				}
				speed = (json[attr] - icur)/8;
				speed = speed>0?Math.ceil(speed):Math.floor(speed);
				
				//	判断临界值
				if(icur != json[attr]){//	有一个属性没达到要求iT,flag就等于false
					flag = false;
				}
				if(attr == "opacity"){
					obj.style.filter = "alpha(opacity:"+(icur+speed)+")";
					obj.style.opacity = (icur+speed)/100;
				}else{
					obj.style[attr] = icur+speed+"px";
				}			
			}
			if(flag){//	全部属性都达到要求iT拉
			    clearInterval(obj.timer);
			    //alert(333);
			    if(fn)fn();
			    //console.log("fn:"+fn);fn();
			}
			//console.log("flag"+flag);
		},30);
}

为自己手动点赞233333,还有好像评论说在IE下有bug,我还没有试

正在回答

9 回答

不,这个对同时运动还是存在bug,flag会被修改为true,然后全部属性并没有到位

0 回复 有任何疑惑可以回复我~
#1

举个栗子233 提问者

我试试
2015-10-20 回复 有任何疑惑可以回复我~
#2

举个栗子233 提问者 回复 举个栗子233 提问者

同学能不能把你测出bug的html代码贴出来?用文字的形式,不要图片哦
2015-10-20 回复 有任何疑惑可以回复我~
#3

举个栗子233 提问者

非常感谢!同学好细心啊
2015-10-21 回复 有任何疑惑可以回复我~

还是不太懂,flag变成false后,怎么变回true,没有这个语句在

0 回复 有任何疑惑可以回复我~
#1

举个栗子233 提问者

在setInterval定时器函数的第一句。
2016-02-10 回复 有任何疑惑可以回复我~

兄弟,我叫你声哥


0 回复 有任何疑惑可以回复我~
#1

举个栗子233 提问者

不必了,女的
2015-11-15 回复 有任何疑惑可以回复我~

给一段我稍加修改的代码:

function motion(obj,data,fn){
	clearInterval(obj.timer);
	obj.timer = setInterval(function(){
		for(var attr in data){
			var attrValue = getStyle(obj,attr),
				sValue = 0,
				speed = 0,
				stop = 0;
			if(attr=='opacity'){
				sValue = Math.round(parseFloat(attrValue)*100);
			}else{
				sValue = parseInt(attrValue);
			}
			speed = (data[attr]-sValue)/8;
			speed = speed>0?Math.ceil(speed):Math.floor(speed);
			if(sValue!=data[attr]){
				stop = 0;
			}else{
				stop++;
			}
			if(attr=='opacity'){
				obj.style.filter = 'alpha(opacity:'+(sValue+speed)+')';
				obj.style.opacity = (sValue+speed)/100;
			}else{
				obj.style[attr] = sValue+speed+'px';
			}
			if(stop==3){
				clearInterval(obj.timer);
				if(fn){
					fn();
				}
			}
		}
	},20);
}
function getStyle(ele,attr){
	if(ele.currentStyle){
	//IE
		return ele.currentStyle[attr];
	}else{
	//非IE
		return getComputedStyle(ele,false)[attr];
	}
}


0 回复 有任何疑惑可以回复我~
#1

举个栗子233 提问者

如果传进的json对不是三个呢?
2015-10-22 回复 有任何疑惑可以回复我~
#2

joker_0042 回复 举个栗子233 提问者

可以增设一个空数组,将attr存储进去,最后将3改为array.length验证
2015-10-22 回复 有任何疑惑可以回复我~
#3

举个栗子233 提问者 回复 joker_0042

嗯,但是调用时变麻烦不可取吧?
2015-10-22 回复 有任何疑惑可以回复我~
#4

joker_0042 回复 举个栗子233 提问者

嗯。开始想的是在传递一个参数或者在json中添加一个存储属性个数的属性len,但没有这样做。 这个框架在做最后一节中鼠标移动到icon图像时图像向上跳动后从下方回到原位置的运动时,透明度的设置不很精确,我想把框架中的透明度处理单独拿出来用,效果会好些,仅作交流。
2015-10-22 回复 有任何疑惑可以回复我~
#5

jellen

if(sValue!=data[attr]){ stop = 0; }else{ stop++; } 应该改为if(sValue==data[attr]){ stop++; }
2015-12-29 回复 有任何疑惑可以回复我~
查看2条回复


     运动后

562718de0001107e05000574.jpg

 


运动前

562718de0001bfd105000605.jpg



这样就看出bug了吧

0 回复 有任何疑惑可以回复我~
#1

举个栗子233 提问者

哈哈哈,我知道你说的bug了,是加了border之后有bug是吧? 然后我看了一下代码,发现其实我早上说的思路是对的,但是代码确实写错了。 if(flag){ clearInterval(obj.timer);if(fn)fn();} 上面这段代码应该放在for-in循环外部执行。也就是执行一边各个属性都达到目标值后flag为true。跳出for-in循环后再执行这段代码。
2015-10-21 回复 有任何疑惑可以回复我~
#2

举个栗子233 提问者

这个bug在上面的问题中修改过来了
2015-10-21 回复 有任何疑惑可以回复我~

你想想,每次进定时器的时候,你修改flag为true,我假设你设置的同时动画有着三个属性好了

{opacity:100,width:1000,height:400}

 if(json[attr]!=current){

                   flag=false;//在某一属性没到设定值时,flag还是被设定为false,可是万一opacity先到达设定值,也就不会进入这个修改操作,flag还是true,这是后面的清除定时器的操作依然会执行,所以width,heigt就不会打到你预想的值,也就是不会到1000

}


0 回复 有任何疑惑可以回复我~
#1

举个栗子233 提问者

我测试了下没有错误呀。然后关于这个问题,你看。 假设初值{opacity:90,width:100,height:100} 目标值{opacity:100,width:200,height:1000}(height增加的比较多) 1、我for-in一轮,假设opacity、width、height均为到达目标值。三个属性均增加一个speed。此时for-in循环结束,flag为false(被置了3次false),定时器未被clearInterval。下一轮30ms,flag在定时器开始时将被置true。
2015-10-21 回复 有任何疑惑可以回复我~
#2

举个栗子233 提问者

2、我再for-in一轮,假设opacity、width均到达目标值,height未达到目标值。开始for-in循环了。执行到opacity、width时【json[attr]!=current】条件不成立,flag未被置false,当执行到height时【json[attr]!=current】,flag被置false。定时器未被clearInterval。循环继续。。下一轮30ms后,flag在定时器开始时将被置true。 3、只有三者均达到目标值。for-in循环中【json[attr]!=current】这一条件一直不成立。flag还是初始的true。此时定时器被清除。
2015-10-21 回复 有任何疑惑可以回复我~

function startMove(obj,json,FnextChange){

    var speed=0;

    var flag=true;

    clearInterval(obj.timer);

    obj.timer=setInterval(function(){

            for(var attr in json){

                flag=true;

                var current=0;//当前属性值

                if(attr=='opacity'){

                    current=Math.round(parseFloat(getStyle(obj,attr))*100);

                }else{

                    current= parseInt(getStyle(obj,attr));

                }



                //计算速度

                speed=(json[attr]-current)/15;

                speed=speed<0?Math.floor(speed):Math.ceil(speed);



                if(json[attr]!=current){

                   flag=false;

                }


               

                //此种设置offsetWidth=border+padding+width,设置内外边距的时候会出现错误

                // obj.style.width=obj.offsetWidth+speed+'px';


                //把属性写到html元素内联里边的话,可以使用obj.style.*获取元素的属性

                    // obj.style.width=parseInt(obj.style.width)+speed+'px';


                //也可以通过api来获取元素属性

                    // ie下

                        // obj.currentStyle[attr];


                    //火狐下

                        // getComputedStyle(obj,false)[attr];

                if(attr=='opacity'){

                    obj.style.opacity=(current+speed)/100;

                    obj.style.filter='alpha:(opacity:'+current+speed+')';

                }else{

                    obj.style[attr]=current+speed+'px';

                }



                

                if(flag){

                    // clearInterval(obj.timer);

                    if(FnextChange){

                        FnextChange();

                    }

                }

                

            }

                // obj.style.fontSize=parseInt(getStyle(obj,'font-size'))+1+'px';

        },30);

    }

function getStyle (obj,attr) {

    if(obj.currentStyle){

        return obj.currentStyle[attr];

    }else{

        return getComputedStyle(obj,false)[attr];

    }

}


0 回复 有任何疑惑可以回复我~
#1

举个栗子233 提问者

同学,是你测试发现了该函数在同时运动中会出现bug的【HTML】代码啦,我想看看是什么bug,我测试了几个案例没有发现bug
2015-10-20 回复 有任何疑惑可以回复我~

http://img1.sycdn.imooc.com//562633c400017b0414221039.jpg最后没去定时器,效果是实现了,但感觉这样不大好

0 回复 有任何疑惑可以回复我~

才是正解

0 回复 有任何疑惑可以回复我~

举报

0/150
提交
取消

关于完美运动框架小bug的修复,附源码

我要回答 关注问题
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号