首页 > 解决方案 > 刷新网页时如何防止倒数计时器重置?

问题描述

我正在设计一个网站,我使用 JavaScript 集成了一个 10 分钟倒计时计时器,该计时器在加载网页时启动。但是,由于我更像是设计师而不是开发人员,所以我不知道如何编辑 JavaScript 代码以使其在重新加载网页时不会重新启动计时器。我知道我必须存储用户 cookie,并且我在网上搜索过,但是当我插入代码时,javascript 代码不起作用。这里有人可以帮助我吗?

const FULL_DASH_ARRAY = 283;
const WARNING_THRESHOLD = 10;
const ALERT_THRESHOLD = 5;

const COLOR_CODES = {
  info: {
    color: "green"
  },
  warning: {
    color: "orange",
    threshold: WARNING_THRESHOLD
  },
  alert: {
    color: "red",
    threshold: ALERT_THRESHOLD
  }
};
<?php
  $timelimit = $rangewaktu;
?>
const TIME_LIMIT = <?php echo $timelimit ?>;
let timePassed = 0;
let timeLeft = TIME_LIMIT;
let timerInterval = null;
let remainingPathColor = COLOR_CODES.info.color;

document.getElementById("app").innerHTML = `
<div class="base-timer">
  <svg class="base-timer__svg" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
    <g class="base-timer__circle">
      <circle class="base-timer__path-elapsed" cx="50" cy="50" r="45"></circle>
      <path
        id="base-timer-path-remaining"
        stroke-dasharray="283"
        class="base-timer__path-remaining ${remainingPathColor}"
        d="
          M 50, 50
          m -45, 0
          a 45,45 0 1,0 90,0
          a 45,45 0 1,0 -90,0
        "
      ></path>
    </g>
  </svg>
  <span id="base-timer-label" class="base-timer__label">${formatTime(
    timeLeft
  )}</span>
</div>
`;

startTimer();

function onTimesUp() {
  clearInterval(timerInterval);
}

function startTimer() {
  timerInterval = setInterval(() => {
    timePassed = timePassed += 1;
    timeLeft = TIME_LIMIT - timePassed;
    document.getElementById("base-timer-label").innerHTML = formatTime(
      timeLeft
    );
    setCircleDasharray();
    setRemainingPathColor(timeLeft);
    
    if (timeLeft === 0) {
      onTimesUp(location.replace('test'));
    }
  }, 1000);
}

function formatTime(time) {
  const minutes = Math.floor(time / 60);
  let seconds = time % 60;

  if (seconds < 10) {
    seconds = `0${seconds}`;
  }

  return `${minutes}:${seconds}`;
}

function setRemainingPathColor(timeLeft) {
  const { alert, warning, info } = COLOR_CODES;
  if (timeLeft <= alert.threshold) {
    document
      .getElementById("base-timer-path-remaining")
      .classList.remove(warning.color);
    document
      .getElementById("base-timer-path-remaining")
      .classList.add(alert.color);
  } else if (timeLeft <= warning.threshold) {
    document
      .getElementById("base-timer-path-remaining")
      .classList.remove(info.color);
    document
      .getElementById("base-timer-path-remaining")
      .classList.add(warning.color);
  }
}

function calculateTimeFraction() {
  const rawTimeFraction = timeLeft / TIME_LIMIT;
  return rawTimeFraction - (1 / TIME_LIMIT) * (1 - rawTimeFraction);
}

function setCircleDasharray() {
  const circleDasharray = `${(
    calculateTimeFraction() * FULL_DASH_ARRAY
  ).toFixed(0)} 283`;
  document
    .getElementById("base-timer-path-remaining")
    .setAttribute("stroke-dasharray", circleDasharray);
}
<div id="app"></div>

强文本

标签: javascripttimer

解决方案


您需要在页面重新加载之前跟踪当前时间,您可以使用 cookie、localStorage 或服务器端来解决此问题。

这是一个带有 cookie 的 1 分钟倒数计时器示例。虽然我将 Node.js 用于服务器端,但由于没有太多服务器端代码,我希望你无论如何都能明白这一点。

服务器端

router.get('/test', (req, res)=>{
   res.render('test', {
      time: req.headers.cookie ? req.headers.cookie.split('time=')[1] : 59 // No cookies = first time loading the page, else get current time value
   })
});

客户端

<div id="timer"></div>
<script>
    let seconds='<%= time %>';
    let timer;
    function countDown(){
        if(seconds < 60){
            document.getElementById("timer").innerText = seconds;
        }
        if(seconds>0){
            seconds--;
            document.cookie = `time=${seconds}`; // update cookie after each second
        }else{
            clearInterval(timer);
        }
    }
    if(!timer){
        timer = window.setInterval(()=>{ 
        countDown();
        }, 1000);
    }
    document.getElementById("timer").innerText='<%= time %>';
</script>

我使用ejs模板语言能够在渲染之前将一些变量传递给 HTML,例如本示例中的当前时间值。

您可以仅对 cookie 执行相同操作,如下所示:

res.cookie('time', req.headers.cookie ? req.headers.cookie.split('time=')[1] : 59);

在服务器端,然后在客户端将 ejs 变量替换'<%= time %>'document.cookie.

希望这至少能让您更清楚地了解工作流程。


推荐阅读