flag = false 是什么时候被重置为true的?

来源:6-2 完美运动框架

六月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函数的。


写回答 关注

12回答

  • 大白杏仁
    2017-08-14 23:11:37

    看完了楼主写的,完全没有毛病,教程代码确实有BUG,不过既然因为 speed = (json[attr] - icur)/8 语句, 当 speed 为0时就能自己停止,为什么教程还要加一大堆检测停止的代码,我发现把那一大段去掉之后功能正常啊,不知道我有没有想错?

  • Robert_Langdon
    2017-05-16 01:35:03

    把flag放外面,最后速度为0,动画是停止了,但是代码一直在运行,无限循环的运行,if(flag)永远到不了

  • Arya_Stark
    2017-04-13 12:09:25

    没仔细看,原来你的代码已经解决了。。

  • Arya_Stark
    2017-04-13 12:02:55

    一、var flag = true; 是放在定时器外面的。

    二、每次启动定时器强制 flag = true。

    三、在for循环外面,再次判断flag。

    六月ovo

    上面我贴出的代码是对的,flag是要放在定时器里面的,每次都需要重置定时器flag=true,视频教程里面是有bug 的。那个for循环的内容仅仅包含动画的执行代码,不包含结束代码,结束代码是在for循环之后的,但是仍然在定时器里面。具体看我上面贴出的完整代码那个回复吧

    2017-04-13 12:14:12

    共 1 条回复 >

  • Arya_Stark
    2017-04-13 11:54:15

    还需要把

    if(flag){

                clearInterval(obj.timer);

                if(fn){

                    fn();

                }

    这一段放在for 循环外面。。.

    -------------手动分割------------------

    楼主,你看看有木有bug,或者你有其他解决方案了没有?

  • Arya_Stark
    2017-04-13 11:49:30

    我去,不行。。

  • 六月ovo
    2017-03-27 17:14:04
    //同步运动函数
    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];
    	}
    }


    Arya_S...

    你好,我发现在第12行代码 for (var attr in json) { 之后 加入第13行代码,flag = true; 强制每次循环之前预设 flag为true,就可以实现链式动画了。 你看看还有其他问题么?

    2017-04-13 11:47:22

    共 1 条回复 >

  • 六月ovo
    2017-03-27 12:24:34

    经过多番测试,视频中的完美运动代码存在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();
         }
    }


    上面讲得比较啰嗦,不知道大家有没有看懂,没看懂的可以照着一步一步去尝试一下,会得到我说的这个结果的

  • 10点
    2017-03-26 17:07:17

    首先我终于找到跟我一样认为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 ){}这个语句就会找到全局变量,所以这就是为什么要放在计时器外

    六月ovo

    噢,代码我打错了,应该是json[attr]的,谢谢纠正。 另外,我还是不太明白,就像你说的,当遇到if(itur != json[attr] )语句的时候就把flag这个全局变量设为false,然后当if(itur != json[attr] )不成立的时候,if( flag ){}这个语句再调用这个全局变量,它不同样是false吗? if(flag)应该是if(flag == true) 的写法对吧? 我还在到处查资料,然后把之前视频写的那个完美框架重新试了一下,好像是没办法执行到链式动画了,也就是没有了后面的fn。

    2017-03-26 18:54:59

    共 1 条回复 >

  • 10点
    2017-03-26 16:15:21

    评论在一楼的那位大哥已经误导了大家,flag放在计时器内会出现bug.

    你的问题我有点看不明白啊哥们,说的明白些

    六月ovo

    我的问题就是,flag=true是放在定时器外面的,对吧?定时器里面是没有代码把flag重置为true的,当第一次代码执行到 if(icur!=iTarget){ flag=false; } 这里的时候,flag就被赋值为false了,之后都没有给flag赋值为true,那么最后是怎么判断到flag=true的呢? 在这里就很不明白,因为没有把flag重置为true的话,其实是没办法执行clearInterval(obj.timer);和之后的fn函数的。

    2017-03-26 16:37:54

    共 1 条回复 >

  • qq_果汁分ni半_03462240
    2017-03-26 15:41:36

    。。。。。好像看错问题,你忽略我的回答吧

  • qq_果汁分ni半_03462240
    2017-03-26 15:38:35

    当最后一个目标完成后,因为setInterval,会重新初始化flag为true

JS动画效果

通过本课程JS动画的学习,从简单动画开始,逐步深入各种动画框架封装

113925 学习 · 1443 问题

查看课程

相似问题