首页 > 解决方案 > 当用户导航到网页中的单独路线时,如何在 JavaScript 中存储计数计时器

问题描述

我正在尝试构建一个网页,该网页允许您在单击开始按钮时启动倒数计时器,并允许您导航到网页上的不同路线启动另一个计时器并导航回第一页和让计时器仍在运行。目前我有和按钮功能工作。但是,我不确定如何让时钟不重置。当我导航到另一个页面时。这个网页主要是用 Python 和 Flask 编写的,但我使用 JavaScript 来实现时间功能。这是我唯一使用过的 JavaScript,其中大部分来自其他帖子。

<div id=time>
<div><span id="hour"></span>:<span id="minute"></span>:<span id="seconds"></span></div>

<button id="start-btn">Start</button>
<button id="stop-btn">Pause</button>
<button id="reset-btn">Reset</button>
      
</div>
<script>
  let hour = 0;
  let minute = 0;
  let seconds = 0;
  let totalSeconds = 0;
  
  let intervalId = null;
  
  function startTimer() {
    ++totalSeconds;
    hour = Math.floor(totalSeconds /3600);
    minute = Math.floor((totalSeconds - hour*3600)/60);
    seconds = totalSeconds - (hour*3600 + minute*60);

    document.getElementById("hour").innerHTML =hour;
    document.getElementById("minute").innerHTML =minute;
    document.getElementById("seconds").innerHTML =seconds;
  }

  document.getElementById('start-btn').addEventListener('click', () => {
    intervalId = setInterval(startTimer, 1000);
  })
  
  document.getElementById('stop-btn').addEventListener('click', () => {
    if (intervalId)
      clearInterval(intervalId);
  });
  
   
  document.getElementById('reset-btn').addEventListener('click', () => {
     totalSeconds = 0;
     document.getElementById("hour").innerHTML = '0';
     document.getElementById("minute").innerHTML = '0';
     document.getElementById("seconds").innerHTML = '0';
  });

</script>

标签: javascriptflask

解决方案


如果您想防止计时器被重置,请使用 cookie 来存储计时器开始的日期。

不要每秒增加计时器,而是用计时器开始的时间减去当前时间。

<!DOCTYPE html>
<html>
<head>
<title>Timer test</title>
</head>
<body>
<div id="time">
    <div><span id="hour"></span>:<span id="minute"></span>:<span id="seconds"></span></div>

    <button id="start-btn">Start</button>
    <button id="stop-btn">Pause</button>
    <button id="reset-btn">Reset</button>

    </div>
    <script type="text/javascript">
      let hour = 0;
      let minute = 0;
      let seconds = 0;
      let pauseTime = null;
      let start = [...document.cookie.matchAll(/([^;=]+)=([^;=]+)(;|$)/g)].filter(x => x[1].trim() == 'timer').map(x => Number(x[2].trim()))[0];
      if(start != null) {
         if(start > 0) start = new Date(start);
         else if(start < 0) { 
           pauseTime = -start;
           start = new Date(Date.now() + start); //+- = -
         } else start = null;
      } else start = null;
      let intervalId = null;


      function startTimer() {
        let totalSeconds;
        if(pauseTime) {
           start = new Date(Date.now() - pauseTime);
           totalSeconds = pauseTime;
           return;
        } else {
           totalSeconds = Math.floor((Date.now() - start.getTime()) / 1000);
        }
        hour = Math.floor(totalSeconds /3600);
        minute = Math.floor((totalSeconds - hour*3600)/60);
        seconds = totalSeconds - (hour*3600 + minute*60);

        document.getElementById("hour").innerHTML =hour;
        document.getElementById("minute").innerHTML =minute;
        document.getElementById("seconds").innerHTML =seconds;
      }
      if(start) intervalId = setInterval(startTimer, 1000);

      document.getElementById('start-btn').addEventListener('click', () => {
         if(pauseTime) {
            pauseTime = null;
         } else {
           if(start) return;
           start = new Date();
           intervalId = setInterval(startTimer, 1000);
         }
         document.cookie = "timer=" + String(start.getTime());
      })

      document.getElementById('stop-btn').addEventListener('click', () => {
        pauseTime = Date.now() - start.getTime();
        document.cookie = "timer=" + String(-pauseTime);
      });


      document.getElementById('reset-btn').addEventListener('click', () => {
         start = null;
         document.cookie = "timer=null";
         if(intervalId) clearInterval(intervalId);
         document.getElementById("hour").innerHTML = '0';
         document.getElementById("minute").innerHTML = '0';
         document.getElementById("seconds").innerHTML = '0';
      });

      </script>
</div>
</body>
</html>

推荐阅读