原生js制作的幻灯片长时间运行后数值计算不准确

问题出现的情况:
假设我是页面访问者,我打开了以下代码写的页面(后面简称:A页面)。这个时候运行a页面十分正确(js动画效果没有出现问题,数值等都不会出现问题)。可我突然想要打开另一张页面(后面简称:B页面),打开B页面后,我忽然有事情离开了电脑,等过个1个多小时我又跑回来了,然后又切换回A页面,问题出现了:
js动画出现问题了,他没有在给定的断点停止动画,总之就是动画的范围值发生了变化.....
正常的时候的初始值:clipboard.png
出问题的时候初始值:clipboard.png

以下是出问题的代码,求大神解决~~~:

<!doctype html>
<html lang="en">
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
   <style>
     body,div{margin:auto;padding:0px;}
     #div{width:200px;height:200px;background-color:blue;opacity:0.6;position:relative;left:0px;top:0px;margin-left:0px;}
     #btn{position:fixed;left:50%;top:50%;margin-left:-30px;margin-top:20px;}
   </style>
   <div id='div'></div>
   <button id='btn'>开始动画</button>
   <script>
     // 获取元素
     function $id(id){
       return document.getElementById(id);
     }
     // 计算样式值
     function $gs(ele,attr){
       if (ele.style[attr]!==''){
         return ele.style[attr];
       }else{
         if (window.getComputedStyle(ele,null)[attr]!=='auto'){
           return window.getComputedStyle(ele,null)[attr];
         }else{
           return 0;
         }
       }
     }
     /*
    • 多属性动画函数

    • ele 元素

            time  动画持续时间
            json  存放改变的属性对象
            fn    回调函数
            delay 是否延迟执行动画
         */
    1. animate(ele,time,json,fn,delay){

           ele.tip=true;
           if (ele.tip===false){
             console.log('正忙!!');
             return ;
           }
           window.setTimeout(function(){
               var startTime=new Date().getTime();
      
               // 存放每个属性相关变化量的数组
               var vals=[];
      
               // 动画流畅度
               var fps=60/1000;
               for (var attr in json)
                {
                  var startVal=(attr.search('opacity')!==-1) ? parseFloat($gs(ele,attr)) : parseInt($gs(ele,attr));
                  var endVal=startVal+json[attr];
                  var unit=(attr.search('opacity')!==-1) ? '' : 'px';
                  vals.push({attr:attr,chg:json[attr],startVal:startVal,endVal:endVal,unit:unit});
                }
               // 开始动画
               function start(){
                 var endTime=new Date().getTime();
      
                 // 当超过给定的运行时间的时候停止动画
                 if (endTime-startTime>=time){
                   ele.tip=true;
                   window.clearTimeout(ele.timer);
                   ele.timer=null;
                   for (var i=0;i<vals.length;++i)
                    {
                      ele.style[vals[i]['attr']]=vals[i]['endVal']+vals[i]['unit'];
                    }
                   // 若有回调函数,则执行
                   if (fn!==undefined && typeof fn==='function'){
      
                     fn();
                   }
                 }else{
                   for (var i=0;i<vals.length;++i)
                    {
                      var speed=vals[i]['chg']*((endTime-startTime)/time);
      
                      ele.style[vals[i]['attr']]=vals[i]['startVal']+speed+vals[i]['unit'];
                    }
                   ele.timer=window.setTimeout(start,1/fps);
                   ele.tip=false;
                 }
               }
               start();
           },(delay===undefined) ? 0 : delay);
          }
          
    2. doit(){

            startAni();
          }
    3. startAni(){

            // width:200 中 200这里是变化量
            animate($id('div'),1000,{width:200,height:200,left:200,top:200,opacity:-0.6},function(){
              animate($id('div'),1000,{width:-200,height:-200,left:-200,top:-200,opacity:0.6},doit,1000);
            },1000);
        // 如上面的参数:现在就固定研究一个width属性。
        //一开始width属性值200,第一次指定动画的时候变化为400,第二次执行动画的时候有变回200,接下去就如此循环:200->400->200->400->200....。
        // 实际本该如此的,可是就我上面给出的那种情况,他就不在指定的范围值停止动画!!!这个怎么解决??求大神空降!!           
          }
          // 点击按钮开始动画
          $id('btn').onclick=startAni;
        </script>
      </body>

      </html>

    阅读 1.7k
    撰写回答
    你尚未登录,登录后可以
    • 和开发者交流问题的细节
    • 关注并接收问题和回答的更新提醒
    • 参与内容的编辑和改进,让解决方法与时俱进
    推荐问题