2

I want to achieve the following scenario:

Set a timer of 60 seconds and start the countdown displaying the timer. After the countdown is finished, refresh (not reload) the page and restart the countdown timer and continue the process.

If the browser's tab is changed, after finishing the timer, refresh the page and pause the timer, and only when the tab is active again refresh the page and start the countdown timer again.

I have managed to achieve the first requirement like:

Result will Refresh in <span id="countdown"></span>
<script>
  if (!document.hidden) {
    function timedRefresh(e) {
      var n = setInterval((function () {
        e > 0 ? (e -= 1, document.getElementById("countdown").innerHTML = e) : (clearInterval(n), window.location.reload())
      }), 1e3)
    }
    timedRefresh(59)
  }
</script>

And is unable to achieve the second requirement. I have tried to implement the solution mentioned here: Is there a way to detect if a browser window is not currently active? But it didn't work.

How do I achieve the requirements in pure JavaScript code?

Maroof Mandal
  • 521
  • 9
  • 29

2 Answers2

1

The following code has solved this scenario. It's a little messy, but I think is understandable. We use both window.document.hasFocus() and the focus event to create this solution. I have changed the window.location.reload() methods to just consoles simulating a function that refresh the data inside the application, since is asked to us refresh (not reload).

    function timedRefresh(intervalTime) {
        let interval = null;
        let currentTime = intervalTime;

        const updateTimer = () => {
            const countdownSpan = document.getElementById("countdown");

            if (currentTime <= 0) {
                console.log(`print refresh at ${new Date()}`); // refresh page
                if (window.document.hasFocus()) {
                    currentTime = intervalTime;
                } else {
                    clearInterval(interval);
                    interval = null;
                    currentTime = intervalTime;
                }
            }

            if (!interval) {
                countdownSpan.innerHTML = "#";
            } else {
                countdownSpan.innerHTML = currentTime;
                currentTime -= 1;
            }
        };

        interval = setInterval(updateTimer, 1000);
        window.addEventListener("focus", () => {
            if (!interval) {
                interval = setInterval(updateTimer, 1000);
            }
        });
    }

    const TIMER_SECONDS = 5;
    timedRefresh(TIMER_SECONDS);

Edit:

The answer above does not work with reloads using window.location.realod(). A code solving the issue may look like this:

  const TIMER_SECONDS = 60;

/* 
 * Update span with current time
 *  `currentTime` is an integer bigger than zero or a string '#' meaning 'timer stopped'
 */
function updateDisplayTimer(currentTime){
  const countdownSpan = document.getElementById("countdown");
  countdownSpan.innerHTML = currentTime;
}

/*
 * A timer with `loopDuration` seconds. After finished, the timer is cleared.
 *  `loopDuration` is an integer bigger than zero, representing the time duration in seconds.
 */
function timedRefresh(loopDuration) {

  let currentTime = loopDuration;
  let interval = setInterval(() => {
    if (currentTime > 0) {
      updateDisplayTimer(currentTime);
      currentTime -= 1;
    } else {
      window.location.reload(); // refresh page
    }
  }, 1000);

  window.addEventListener('load', () => {
    if(window.document.hasFocus()){
      timedRefresh(TIMER_SECONDS);
    } else {
      updateDisplayTimer("#");
      clearInterval(interval);
      interval = null;
    }
  });

  window.addEventListener('focus', () => {
    if(interval == null){
      window.location.reload(); // refresh page
    }
  });
}

// exeute main fucntion 
timedRefresh(TIMER_SECONDS);
  • The page keeps reloading even after the tab is changed. It should reload only once. – Maroof Mandal Jun 18 '22 at 15:44
  • Have you switched the ```console.log(`print refresh at ${new Date()})`; // refresh page``` with `window.location.reload()`? If you do so, this code will not work properly. When the window has loaded, the function `timedRefresh` is called again, and the variables inside the function scope are cleared. Maybe I can find some answer to this case. – Rafael Barbosa Jun 20 '22 at 15:36
  • I did. Refreshing the page is the primary requirement. – Maroof Mandal Jun 21 '22 at 13:56
  • What about now? I've edited the answer. Is that right? – Rafael Barbosa Jun 22 '22 at 15:53
0

Use window.document.hasFocus() to determine if the user is focused on your webpage or not.

  • Can you post the logic of the second part in pure JS? – Maroof Mandal Jun 14 '22 at 15:16
  • The function returns true if your window is focused. SO before starting your timer, check if window has focus, and if not, pause the timer. –  Jun 14 '22 at 15:17