qq_42669510 2023-08-28 16:33 采纳率: 73.3%
浏览 7
已结题

JS时钟旋转案例类似bug


<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .clock {
        width: 250px;
        height: 250px;
        border: 8px solid #000;
        border-radius: 50%;
        margin: 100px auto;
        position: relative;
      }

      .line {
        /* 1.定位 */
        position: absolute;
        width: 4px;
        height: 250px;
        background-color: #999;
        left: 50%;
        transform: translate(-50%);
      }

      /* 线2: 旋转, 每条线旋转角度不同, 单独选中不同的line, 写rotate代码 */
      /* 一圈是360度, 等分成  xx 份 */
      .line:nth-child(2) {
        transform: translate(-50%) rotate(30deg);
      }

      .line:nth-child(3) {
        transform: translate(-50%) rotate(60deg);
      }

      .line:nth-child(4) {
        transform: translate(-50%) rotate(90deg);
      }

      .line:nth-child(5) {
        transform: translate(-50%) rotate(120deg);
      }

      .line:nth-child(6) {
        transform: translate(-50%) rotate(150deg);
      }

      /* 第一根和第四跟宽度大一些 */
      .line:nth-child(1),
      .line:nth-child(4) {
        width: 5px;
      }

      /* 遮罩圆形 */
      .cover {
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
        width: 200px;
        height: 200px;
        background-color: #fff;
        border-radius: 50%;
      }

      /* 表针 */
      /* 并集选择器放在单独选择器的上面, 避免transform属性的层叠 */
      .hour,
      .minute,
      .second {
        position: absolute;
        left: 50%;
        /* 盒子底部在盒子中间 */
        bottom: 50%;
      }

      .hour {
        width: 6px;
        height: 50px;
        background-color: #333;
        margin-left: -3px;
        transform-origin: center bottom;
      }

      .minute {
        width: 5px;
        height: 65px;
        background-color: #333;
        margin-left: -3px;
        transform-origin: center bottom;
      }

      .second {
        width: 4px;
        height: 80px;
        background-color: red;
        margin-left: -2px;
        transform-origin: center bottom;
      }

      /* 螺丝 */
      .dotted {
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
        width: 18px;
        height: 18px;
        background-color: #333;
        border-radius: 50%;
      }
    </style>
  </head>

  <body>
    <div class="clock">
      <!-- 刻度线 -->
      <div class="line"></div>
      <div class="line"></div>
      <div class="line"></div>
      <div class="line"></div>
      <div class="line"></div>
      <div class="line"></div>

      <!-- 遮罩圆形 -->
      <div class="cover"></div>
      <!-- 表针 -->
      <div class="hour"></div>
      <div class="minute"></div>
      <div class="second"></div>

      <!-- 螺丝 -->
      <div class="dotted"></div>
    </div>
    <script>
      const hour = document.querySelector('.hour')
      const minute = document.querySelector('.minute')
      const second = document.querySelector('.second')

      let miao = 0
      let fen = 0
      let shi = 0
      let s = setInterval(function () {
        miao += 6
        second.style.transform = `rotate(${miao}deg)`
      }, 1000)

      let min = setInterval(function () {
        fen += 6
        minute.style.transform = `rotate(${fen}deg)`
      }, 60000)

      let h = setInterval(function () {
        shi += 30
        hour.style.transform = `rotate(${shi}deg)`
      }, 3600000)
    </script>
  </body>
</html>

为什么这段代码在浏览器运行时间长了,分针会出现提前动?

  • 写回答

3条回答 默认 最新

  • z a x 2023-08-28 17:11
    关注

    我看你的代码中分针、秒针、时针的旋转使用了setInterval来实现。但是setInterval并不是特别的精确,它依赖于浏览器的事件循环机制,可能会受到性能等多方面因素的影响,从而导致时间的不准确。

    从你的代码中,分针每次旋转 6 度,秒针每秒旋转 6 度,时针每小时旋转 30 度。这种方式下,时间的计算不够精确,可能会导致分针出现提前动的情况,特别是在运行时间较长时更容易出现问题。

    你可以考虑使用requestAnimationFrame代替setInterval来实现动画效果。requestAnimationFrame会在浏览器下一次重绘之前调用指定的回调函数,可以更好地控制动画的精确性。

    const hour = document.querySelector('.hour')
    const minute = document.querySelector('.minute')
    const second = document.querySelector('.second')
    
    function updateClock() {
      const now = new Date()
    
      const milliseconds = now.getMilliseconds()
      const seconds = now.getSeconds()
      const minutes = now.getMinutes()
      const hours = now.getHours()
    
      const miao = seconds * 6 + milliseconds * 0.006
      const fen = minutes * 6 + seconds * 0.1
      const shi = hours * 30 + minutes * 0.5
    
      second.style.transform = `rotate(${miao}deg)`
      minute.style.transform = `rotate(${fen}deg)`
      hour.style.transform = `rotate(${shi}deg)`
    
      requestAnimationFrame(updateClock)
    }
    
    updateClock()
    

    上面使用了requestAnimationFrame来循环调用updateClock函数,该函数会获取当前的时间,并计算分针、秒针、时针的旋转角度,然后应用于相应的元素。这样可以比较准确地控制动画效果,避免时间偏差问题。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 9月5日
  • 已采纳回答 8月28日
  • 创建了问题 8月28日

悬赏问题

  • ¥15 esp32驱动GC9A01循环播放视频
  • ¥15 惠普360g9的最新bios
  • ¥15 配置hadoop时start-all.sh老是启动失败
  • ¥30 这个功能用什么软件发合适?
  • ¥60 微信小程序,取消订单,偶尔订单没有改变状态
  • ¥15 用pytorch实现PPO算法
  • ¥15 关于调制信号的星座图?
  • ¥30 前端传参时,后端接收不到参数
  • ¥15 这是有什么问题吗,我检查许可证了但是显示有呢
  • ¥15 机器学习预测遇到的目标函数问题