0

The code below sends the 30s event do Google Analytics after 30 seconds a user enters a page.

setTimeout(function(){
   gtag('event', '30s');
}, 30000);

But when the user minimizes the window, the event still fires.

What I really want is a way to "pause" the setTimeout when the user minimizes the page and, when he maximizes the page, the setTimeout continues counting from the moment it has stopped.

I tried to put setTimeout inside the hasFocus statement but it didn't work as expected.

Any way to do that?

2 Answers2

1

You can use the page visibility API to detect when page focus is lost. When hidden, clear the existing timeout, and set the time remaining into a variable; when shown, set a setTimeout with the remaining time. Something along the lines of:

let run = false;
const fn = () => {
  gtag('event', '30s');
  run = true;
};
let timeoutId;
let runAt;
let timeLeft = 30_000;
const resume = () => {
  runAt = Date.now() + timeLeft;
  timeoutId = setTimeout(fn, timeLeft);
};
resume();

document.addEventListener('visibilitychange', () => {
  if (document.hidden) {
    timeLeft = runAt - timeLeft;
    clearTimeout(timeoutId);
  } else if (!run) {
    resume();
  }
});
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
1

You can use document.hidden:

setInterval(() => console.log(document.hidden), 1000)
sonEtLumiere
  • 4,461
  • 3
  • 8
  • 35