skip to Main Content

I tested a simple timer code for showing timer in website. The timer working fine when i am on the page. But when I go the another page or site, after a while when I come back to the timer page i see that timer did not worked correctly in the interval.
Suppose I leave the page for 5 minutes. So when I will come back, I should see 00:05:00. But it is displaying 00:01:00 (around).
But if I dont leave the page it is working fine.
What is the solution?

timerElement = document.getElementById("time");
let seconds = 0, minutes = 0,  hours = 0;
timerInterval = setInterval(function() {
  seconds++;

  if (seconds === 60) {
    seconds = 0;
    minutes++;

    if (minutes === 60) {
      minutes = 0;
      hours++;
    }
  }

  const formattedTime = `${String(hours).padStart(2, "0")}:${String(minutes).padStart(2, "0")}:${String(seconds).padStart(2, "0")}`;
  timerElement.textContent = formattedTime;
}, 1000);
<h1 id="time"></h1>

Even I deployed this on github page. But result is same.

2

Answers


  1. this one will do the job of real elapsed time on reactivate window, with no error when it’s in system standby

    const
      timerElement = document.querySelector('#timer-element')
    , Digits2      = t => t<10 ? `0${t}` : t
    , one_Sec      = 1000
    , one_Min      = one_Sec * 60
    , one_Hour     = one_Min * 60
    , ZeroTime     = new Date().getTime()
      ;
    setInterval(()=>
      {
      let tim = new Date().getTime() - ZeroTime
        , h   = Math.floor( tim / one_Hour)
        , m   = Math.floor((tim % one_Hour) / one_Min )
        , s   = Math.floor((tim % one_Min ) / one_Sec )
        ;
      timerElement.textContent = `${Digits2(h)}:${Digits2(m)}:${Digits2(s)}`
      },500);
    <h1 id="timer-element"></h1>

    If you look for more elaborate : see there

    Login or Signup to reply.
  2. setInterval and setTimeout call their callback not in precise time. When a page is on a hidden tab the browser could postpone/throttle callbacks.

    I would suggest to try requestAnimationFrame (which isn’t called on a hidden tab which is good) and compare the current time to the timer’s start time. Using requestAnimationFrame would give more precise the timer’s updating on the screen.

    Formatting could be done with Intl.DateTimeFormat (used here to simplify the example, needs some tweaks to handle hours > 24):

    const start = new Date, today = new Date;
    today.setHours(0, 0, 0, 0);
    let running = true;
    
    const format = new Intl.DateTimeFormat('en', {
      hourCycle: 'h23',
      hour: '2-digit',
      minute: '2-digit',
      second: '2-digit',  
      fractionalSecondDigits: 2
    });
    // add today's timestamp so the timezone would be properly handled
    const timer = () => requestAnimationFrame(() => {
      $time.textContent = format.format(new Date - start + +today);
      running && timer();
    });
    
    timer();
    console.log('started');
    button{
      padding: 10px;
      min-width: 100px;
      border-radius: 5px;
      cursor:pointer;
      background:lightblue;
    }
    <h1 id="$time" style="font-family:monospace"></h1>
    <button onmousedown="running = false">Stop</button>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search