js 涉及闭包中变量引用的bug,找不到原因。

代码如下,不知道为什么不会执行改变高度和透明度的动画。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style type="text/css">
        #box{ height: 200px; width: 200px; position: absolute; background: #999; left: 10px; top:0px; opacity: .8; filter: alpha(opacity:80);}
        button{ position: relative;  top:300px; }
    </style>
</head>
<body>
    <div id="box"></div>
    <button type="button">移动</button>

    <script type="text/javascript">
        window.onload=function(){
            function getStyle(obj,className){
                var val=(obj.currentStyle? obj.currentStyle[className]:getComputedStyle(obj,false)[className]);
                if(className=="opacity"){
                    val=Math.round(parseFloat(val)*100);
                }
                return parseInt(val);
            }
            /*-----move函数--------*/
             move=function(obj,json_move,move_time){
                clearInterval(obj.timer);
                if(!obj.arr){
                    obj.arr=[];
                }
                function add(){
                    if(arguments.length>0){
                        obj.arr.push(arguments);
                    }
                    return add;
                }
                var time=null;
                var selt={
                    "fast":600,
                    "normal":800,
                    "slow":2200
                }
                switch (typeof move_time){
                    case "string":
                        if(selt.hasOwnProperty(move_time)){
                            time=selt[move_time];
                        }else{
                            time=selt[normal];
                        };
                        break;
                    case "number":
                        time=move_time;
                        break;
                    default:
                        time=selt[normal];
                        break;
                }
                var n=0;
                var count=parseInt(time/30);
                var start={};
                var dis={};
                for(var key in json_move){
                    start[key]=getStyle(obj,key);
                    dis[key]=json_move[key]-start[key];
                }
                obj.timer=setInterval(function(){
                    n++;
                    for(var key in json_move){
                        if(key=="opacity"){
                            obj.style.opacity=(start[key]+dis[key]/count*n)/100;
                            obj.style.filter="alpha(opacity:"+start[key]+dis[key]/count*n+")";
                        }else{
                            obj.style[key]=start[key]+dis[key]/count*n+"px";
                        }
                        if(n==count){
                            clearInterval(obj.timer);
                            if(obj.arr.length!=0){
                                console.log("----------------");
                                console.log(obj.arr);
                                var temp=obj.arr.shift();
                                console.log(temp);
                                console.log(obj.arr);
                                console.log("-----------------");
                                move(obj,temp[0],temp[1]);
                            }
                        }
                    }
                },30);
                return add;
            }

            /*-----------------------*/

            /*----------------------*/
            var m_div=document.getElementById("box");
            var m_btn=document.getElementsByTagName("button")[0];
            m_btn.onclick=function(){
                move(m_div,{"left":300},1000)({"width":400},1000)({"top":400, "opacity":50},2000)({"height":0,"opacity":80},1000);
            }
        }
    </script>
</body>
</html>

2个回答


                obj.timer = setInterval(function () {
                    n++;
                    for (var key in json_move) {
                        if (key == "opacity") {
                            obj.style.opacity = (start[key] + dis[key] / count * n) / 100;
                            obj.style.filter = "alpha(opacity:" + start[key] + dis[key] / count * n + ")";
                        } else {
                            obj.style[key] = start[key] + dis[key] / count * n + "px";
                        }
                    }
                    //放出来,放里面因为你上一次操作有2个属性要设置,会导致执行2次这个代码
                    //第一次执行设置top属性时已经更新了最后一个动作的timer句柄,第二次for设置opacity属性时这个代码直接干掉了新启动的timer
                    if (n == count) {
                        clearInterval(obj.timer);///
                        if (obj.arr.length != 0) {

                            console.log("----------------");
                            console.log(obj.arr);
                            var temp = obj.arr.shift();
                            console.log(temp);
                            console.log(obj.arr);
                            console.log("-----------------");
                            move(obj, temp[0], temp[1]);
                        }
                    }
                    /////////////////////////////////
                }, 30);
hiaia
今天的风儿有点喧嚣 对不起,我知道错在哪里了,是我犯了一个很低级的错误,多谢指点,好像前面几个问题也是你回答我的,太感谢你了!
接近 4 年之前 回复
hiaia
今天的风儿有点喧嚣 什么意思,没懂,是在执行完“left”、“width”、“‘top’,‘opacity’”动画以后执行“‘height’,‘opacity’”动画时 再次调用了move函数,变量n和count在move函数体内初始化过,但是在设置的循环函数中获取到的n和count值是上一个动画结束时n和count的值?
接近 4 年之前 回复

动画自己写?为什么不用JQuery?

hiaia
今天的风儿有点喧嚣 Jquery确实方便,但有时候用原生js写可能会更灵活。
接近 4 年之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐