ggbba@ 2023-03-29 22:24 采纳率: 33.3%
浏览 75
已结题

js运动函数定时器没办法清除

<body>
  <button id="begin">开始运动</button>
  <button id="stop">停止运动</button>
  <div></div>
  <script>
    let begin = document.querySelector('#begin');
    let cease = document.querySelector('#stop');
    let div = document.querySelector('div');
    /* let target = 600;
    let direction = "top" */
    let timer;
    
    begin.onclick = function () {
      animate(div, {left:0,top:0});
    }

    function animate(el, obj) {
      
      timer = setInterval(() => {
        let count =0;
        for (key in obj) {
          let target = obj[key];
          let current = parseInt(getComputedStyle(el)[key]);
          console.log(obj.current);

          let speed = (target - current) / 10;
          console.log(target,current);
          if (speed < 0) {
            speed = Math.floor(speed);
          } else {
            speed = Math.ceil(speed);
          } 
          el.style[key] = current + speed + "px";
          //当前的值等于目标值清除定时器
          if (speed == 0) {
              clearInterval(timer);
            }
        }
      }, 200);
    }
    cease.onclick = function () {
      clearInterval(timer);
    }


  </script>


![img](https://img-mid.csdnimg.cn/release/static/image/mid/ask/806616990086139.jpg "#left")

原来位置left: 50px; top: 400px;
js目标移动到left:0,top:0
执行完left后定时器就停止了,top还没走到0

img

  • 写回答

3条回答 默认 最新

  • 社区专家-Monster-XH 2023-03-29 22:37
    关注

    基于Monster 组和GPT的调写:
    代码中有一个问题是在 setInterval 中使用了一个 for...in 循环遍历对象的属性,而在循环中使用了一个变量 key,但在 console.log(obj.current) 中又将它写成了 obj.current,这样会导致输出 undefined。正确的写法应该是 console.log(current)。

    另一个问题是,当多个属性的动画同时进行时,只要其中一个属性的动画到达目标值就会清除定时器,这会导致其他属性的动画还没有完成就被中止了。

    为了解决这个问题,要在每次循环中记录当前所有属性的动画是否都已完成,只有所有属性的动画都完成了,才清除定时器。

    以下是修改后的代码

    
    
    <body>
      <button id="begin">开始运动</button>
      <button id="stop">停止运动</button>
      <div style="position: absolute; left: 50px; top: 400px;">Hello, world!</div>
      <script>
        let begin = document.querySelector('#begin');
        let cease = document.querySelector('#stop');
        let div = document.querySelector('div');
        let timer;
    
        begin.onclick = function () {
          animate(div, {left: 0, top: 0});
        }
    
        function animate(el, obj) {
          clearInterval(timer);
          timer = setInterval(() => {
            let allFinished = true;
            for (let key in obj) {
              let target = obj[key];
              let current = parseInt(getComputedStyle(el)[key]);
              let speed = (target - current) / 10;
              if (speed < 0) {
                speed = Math.floor(speed);
              } else {
                speed = Math.ceil(speed);
              } 
              el.style[key] = current + speed + "px";
              if (current !== target) {
                allFinished = false;
              }
            }
            if (allFinished) {
              clearInterval(timer);
            }
          }, 200);
        }
    
        cease.onclick = function () {
          clearInterval(timer);
        }
      </script>
    </body>
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(2条)

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 3月29日
  • 已采纳回答 3月29日
  • 赞助了问题酬金15元 3月29日
  • 创建了问题 3月29日

悬赏问题

  • ¥15 delphi webbrowser组件网页下拉菜单自动选择问题
  • ¥15 wpf界面一直接收PLC给过来的信号,导致UI界面操作起来会卡顿
  • ¥15 init i2c:2 freq:100000[MAIXPY]: find ov2640[MAIXPY]: find ov sensor是main文件哪里有问题吗
  • ¥15 运动想象脑电信号数据集.vhdr
  • ¥15 三因素重复测量数据R语句编写,不存在交互作用
  • ¥15 微信会员卡等级和折扣规则
  • ¥15 微信公众平台自制会员卡可以通过收款码收款码收款进行自动积分吗
  • ¥15 随身WiFi网络灯亮但是没有网络,如何解决?
  • ¥15 gdf格式的脑电数据如何处理matlab
  • ¥20 重新写的代码替换了之后运行hbuliderx就这样了