Js BOM中用定时器实现简单运动会遇到的一些小问题及解决

  • 简单运动

    • 简单运动:是一种视觉暂留效果,只要元素变化过程时间够短,给人眼造成的效果就是一个运动的效果,人眼的视觉残留的时间0.1~0.4 s
    • 可以通过定时器,实现每隔一个极短时间(50~100毫秒左右),执行函数,函数内部让运动的属性值发生变化
  • 定时器常见问题1

    • 将定时器的开始和停止过程写在不同的事件函数内部,容易出现用户错误点击情况:

      简单运动的代码如下:


      image.png
 <html>
        <head>
            <meta charset="UTF-8">
            <meta http-equiv="X-UA-Compatible" content="IE=edge">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>Document</title>
            <style>
                #box{
                    width: 100px;
                    height: 100px;
                    position: absolute;
                    left: 0;
                    background-color: lightcoral;
                }
            </style>
        </head>
        <body>
        <input type="button" id="start" value="开始">
        <input type="button" id="end" value="停止">
        <div id="box"></div>
    
        <script>
            var start = document.getElementById("start");
            var end = document.getElementById("end");
            var box = document.getElementById("box");
            
           //信号量  -- 全局变量存储left的属性值,每次都会发生变化实现移动
            var boxleft = 0;//初始值必须与box的初始属性值一样
            var boxInveral;
            start.onclick = function(){
              boxInveral = setInterval(function(){
                    boxleft += 10;
                    box.style.left = boxleft + "px"; 
                },100);
            };
    
            //清除定时器
            end.onclick = function(){
                clearInterval(boxInveral);
            }
        </script>
        </body>
        </html>
    
  • 定时器常见问题1
    • 将定时器的开始和停止过程写在不同的事件函数内部,容易出现用户错误点击情况:
    • 多次点击开始,会造成加速 :(每一个定时器都是独立的,每点击一次,就相当于再+10,造成加速);
      多次点击开始,不能够停止 :(清除定时器,清除的是当前最新的定时器,而前面设置的全局变量存储的定时器,在你每点击一次开始按钮,就会改变其指向,指向最新的定时器,所以清除定时器,只能清除当前最新的定时器。而前面的那些点击生成的定时器没有办法引用到,也就没有办法再去清除了);
    • 解决方法:设表先关,每次开启新定时器之前,先清除一次前面的定时器,这样就会永远保留当前最新的定时器。
      <script>
            var start = document.getElementById("start");
            var end = document.getElementById("end");
            var box = document.getElementById("box");
            
           //信号量  -- 全局变量存储left的属性值,每次都会发生变化实现移动
            var boxleft = 0;//初始值必须与box的初始属性值一样
            var boxInveral;
            start.onclick = function(){
            //定时器写在事件函数内部,当事件多次被触发,会导致定时器累积
            //解决方法:设表先关
              clearInterval(boxInveral);//关闭之前的定时器
              boxInveral = setInterval(function(){
                    boxleft += 10;
                    box.style.left = boxleft + "px"; 
                },100);
            };
    
            //清除定时器
            end.onclick = function(){
                clearInterval(boxInveral);
            }
        </script>
  • 定时器常见问题2

    • 要求让元素走到指定位置停止,如果步长设置不合理,停止的位置可能就不是指定位置。

    • 解决方法:拉钟停表,在定时器内部每次都要判断是否走到了终点,要不要停止定时器;

      如果走到或超过了终点,强行拉到终点,并停止定时器

<script>
        var start = document.getElementById("start");
        var end = document.getElementById("end");
        var box = document.getElementById("box");
        
       //信号量  -- 全局变量存储left的属性值,每次都会发生变化实现移动
        var boxleft = 0;//初始值必须与box的初始属性值一样
        var boxInveral;
        start.onclick = function(){
            clearInterval(boxInveral);
          boxInveral = setInterval(function(){
                // boxleft += 10;
                // boxleft += 20;
                // boxleft += 30;//当前进设置的逐渐变大,最终停下来的位置也不是指定位置了
                boxleft += 35;                
                //判断这一次的运动是否走到了指定500px位置
                if(boxleft >= 500){
                    // 解决上面问题方法就是 强行拉到指定位置,直接给变量赋值指定位置
                    box.style.left = 500 + "px";
                    // 清除定时器
                    clearInterval(boxInveral);
                }
                box.style.left = boxleft + "px"; 
            },100);
        };

        //清除定时器
        end.onclick = function(){
            clearInterval(boxInveral);
        }
    </script>
  • 定时器常见问题3

    • 要求规定时间内让元素走到规定的结束位置,时间间隔可以更改

    • 解决方法:步标整除。

      总距离 = 步长 * 次数;

      时间间隔自定义,总时长固定;

      求出总次数 = 总时间 / 时间间隔

      定义计数器变量,每执行一次定时器函数加1,直到执行达到总次数,停止定时器

    • 如:3秒,让div从100px走到700px

      <html>
      <head>
          <style>
              #box{
                  width: 100px;
                  height: 100px;
                  position: absolute;
                  left: 100px;
                  background-color: lightcoral;
              }
          </style>
      </head>
      <body>
          <input type="button" id="start" value="开始">
          <input type="button" id="end" value="停止">
          <div id="box"></div>
      
          <script>
              var start = document.getElementById("start");
              var end = document.getElementById("end");
              var box = document.getElementById("box");
      
              //已知 开始位置、结束位置、总时长、时间间隔
              // 总距离 = 步长 * 总次数
              // 总距离可以由 开始位置 减 结束位置 得到;已知
              // 总次数由 总时长 / 时间间隔 得到;已知
              // 所以  步长 = (开始位置 减 结束位置)/(总时长 / 时间间隔);
      
              
             //信号量 ,相当于初始值
              var boxleft = 100;//初始值必须与box的初始属性值一样
              var endleft = 700;//结束位置
              var time = 1000;//总时长
              var interval = 50;//时间间隔
              var step = (endleft - boxleft)/(time / interval);//步长
      
              var boxInveral;
      
              var count = 0;//定义一个次数的累加器
      
              start.onclick = function(){
                clearInterval(boxInveral);
                boxInveral = setInterval(function(){
                      //每次加步长
                      boxleft += step;     
                      //每运动一次,累加器加1
                      count ++;    
                      //判断是否达到总次数
                      if(count >= (time / interval)){
                          //由于总距离与总时长可能求出的次数不是整数,这样最后停下来的位置也肯可能不准
                          // 拉钟停表
                          boxleft = endleft;
                          clearInterval(boxInveral);
                       
                      }
                      box.style.left = boxleft + "px"; 
                  },interval);
              };
      
              //清除定时器
              end.onclick = function(){
                  clearInterval(boxInveral);
              }
          </script>
      </body>
      </html>
      
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,192评论 6 511
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,858评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,517评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,148评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,162评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,905评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,537评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,439评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,956评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,083评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,218评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,899评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,565评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,093评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,201评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,539评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,215评论 2 358

推荐阅读更多精彩内容

  • window对象 window是bom中的顶层对象,其他的对象都是Window的子对象 document对象就是w...
    lrsoy_阅读 244评论 0 0
  • BOM的概念 浏览器对象模型,提供了独立于内容的,可以与浏览器窗口进行互动的对象结构。BOM由多个对象组成,其中代...
    amanohina阅读 253评论 0 0
  • BOM BOM 是指浏览器对象的模型,浏览器对象模型提供了独立于内容的、可以与浏览器窗口进行交互的对象结构。BOM...
    GongShengM阅读 370评论 0 0
  • 多重条件判断语句 if语句 语法三: if(条件表达式){ 语句... }else if(条件表达式){ 语句.....
    々_18C阅读 563评论 0 0
  • 高级定时器 关于定时器要记住的最重要的事情是:指定的时间间隔表示何时将定时器的代码添加到队列,而不是何时实际执行代...
    风吹燕尾阅读 540评论 0 1