Quiero lograr el siguiente escenario:
Configure un temporizador de 60 segundos y comience la cuenta regresiva mostrando el temporizador. Una vez finalizada la cuenta regresiva, actualice (no vuelva a cargar) la página y reinicie el temporizador de cuenta regresiva y continúe el proceso.
Si se cambia la pestaña del navegador, después de finalizar el temporizador, actualice la página y pause el temporizador, y solo cuando la pestaña esté activa nuevamente, actualice la página y vuelva a iniciar el temporizador de cuenta regresiva.
He logrado cumplir el primer requisito como:
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>Y es incapaz de lograr el segundo requisito. He intentado implementar la solución mencionada aquí: ¿Hay alguna forma de detectar si una ventana del navegador no está actualmente activa? Pero no funcionó.
¿Cómo logro los requisitos en código JavaScript puro?
El siguiente código ha resuelto este escenario. Es un poco desordenado, pero creo que es comprensible. Usamos window.document.hasFocus() y el evento de enfoque para crear esta solución. He cambiado los métodos window.location.reload() a solo consolas que simulan una función que actualiza los datos dentro de la aplicación, ya que se nos solicita actualizar (no recargar) .
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);Editar:
La respuesta anterior no funciona con recargas usando window.location.realod() . Un código que resuelve el problema puede verse así:
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);Use window.document.hasFocus() para determinar si el usuario está enfocado en su página web o no.