Run setTimeout only when tab is active - javascript

Is there a way to stop setTimeout("myfunction()",10000); from counting up when the page isn't active. For instance,
A user arrives at a "some page" and stays there for 2000ms
User goes to another tab, leaves "some page" open.
myfunction() doesn't fire until they've come back for another 8000ms.

(function() {
var time = 10000,
delta = 100,
tid;
tid = setInterval(function() {
if ( document.hidden ) { return; }
time -= delta;
if ( time <= 0 ) {
clearInterval(tid);
myFunction(); // time passed - do your work
}
}, delta);
})();
Live demo: https://jsbin.com/xaxodaw/quiet
Changelog:
June 9, 2019: I’ve switched to using document.hidden to detect when the page is not visible.

Great answer by Šime Vidas, it helped me with my own coding. For completeness sake I made an example for if you want to use setTimeout instead of setInterval:
(function() {
function myFunction() {
if(window.blurred) {
setTimeout(myFunction, 100);
return;
}
// What you normally want to happen
setTimeout(myFunction, 10000);
};
setTimeout(myFunction, 10000);
window.onblur = function() {window.blurred = true;};
window.onfocus = function() {window.blurred = false;};
})();
You'll see that the window blurred check has a shorter time set than normal, so you can set this depending on how soon you require the rest of the function to be run when the window regains focus.

You can do something like:
$([window, document]).blur(function() {
// Clear timeout here
}).focus(function() {
// start timeout back up here
});
Window is for IE, document is for the rest of the browser world.

I use almost the same approach as Šime Vidas in my slider
but my code is based on document.visibilityState for page visibility checking:
document.addEventListener("visibilitychange", () => {
if ( document.visibilityState === "visible" ) {
slideshow.play();
} else {
slideshow.pause();
}
});
About Page Visibility
API: https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API

What you'd have to do is set up a mechanism to set timeouts at small intervals, keeping track of total elapsed time. You'd also track "mouseenter" and "mouseleave" on the whole page (the <body> or something). When the short-term timeouts expire, they can check the window state (in or out) and not restart the process when the window is not in focus. The "mouseenter" handler would start all paused timers.
edit — #Šime Vidas has posted an excellent example.

I've finally implemented a variation of #Šime Vidas' answer, because the interval was still running if I opened another program and the browser window was not visible, but the page executing the interval was the active browser tab. So, I've modified the condition to document.hidden || !document.hasFocus(). This way, if the document is hidden or the document doesn't have the focus, the interval function just returns.
(function() {
var time = 10000,
delta = 100,
tid;
tid = setInterval(function() {
if ( document.hidden || !document.hasFocus() ) { return; }
time -= delta;
if ( time <= 0 ) {
clearInterval(tid);
myFunction(); // time passed - do your work
}
}, delta);
})();

Related

Reset timer on mousemove and keypress

The below javascript code auto refresh the page every 10 sec.
My question is how can I reset the timer on mousemove and keypress.
Java-Script
<script type="text/javascript" language="JavaScript">
var secs;
var timerID = null;
var timerRunning = false;
var delay = 1000;
function InitializeTimer(seconds) {
//length of the timer, in seconds
secs = seconds;
StopTheClock();
StartTheTimer();
}
function StopTheClock() {
if (timerRunning)
clearTimeout(timerID);
timerRunning = false;
}
function StartTheTimer() {
if (secs == 0) {
StopTheClock();
window.location.href = window.location.href;
}
else {
document.getElementById("lbltime").innerText = secs + " ";
secs = secs - 1;
timerRunning = true;
timerID = self.setTimeout("StartTheTimer()", delay);
}
}
</script>
Thank you in advance.
If I understood you correctly, something like this (really basic example: the timer is reset on mousemove and keypress):
var elem = document.getElementById("timer"), timeout, startTimer = function timer() {
elem.textContent++;
timeout = setTimeout(timer, 1000)
}
function resetTimer() {
// here you reset the timer...
clearTimeout(timeout);
elem.textContent = -1;
startTimer();
//... and also you could start again some other action
}
document.addEventListener("mousemove", resetTimer);
document.addEventListener("keypress", resetTimer);
startTimer();
<span id="timer">-1</span> - Move cursor or press a key to reset timer.
As I guess, you want to delay page reloading if there was some user activity on the page. In your reload() function you just need to check, if timer's value reached the limit (like 60 seconds). If yes, execute reloading. However, notice, that handling mousemove event can make browser's tab have high CPU usage, if, for example, I just start to move my cursor quickly. You might want to pick some important areas and set handlers on the corresponding elements. For example, keypress event can be listened to only on a comment form or mousemove can be listened to only on a menu or on an article.
PS. Also take into account that
The keypress event is fired when a key is pressed down, and that key normally produces a character value
so, if user presses, for example, ctrl or alt the event will not be fired.
Your code seems a bit too branched out in my opinion, what I would do is simplify it a bit.
window.refreshTimeout = null;
function refreshPage(){
location.reload();
}
function refresh(){
clearTimeout(window.refreshTiemout);
window.refreshTimeout = setTimeout(refreshPage, 2000)
}
window.refreshTimeout = setTimeout(refreshPage, 2000)
window.addEventListener('mousemove', refresh)
<h4>HelloWorld</h4>
As you can see, you attach an event listener to the window for a mouse move (you can attach others too) within which you cancel the previous timeout and start a new one. Initially you of course start a timeout.

Only setTimeout executes function. JS

I am trying to implement kind of player on my website.
If press 'Play' button, the music starts and the page smoothly scrolls down.
But when you press 'Mute' button (function(){music.volume=0}) I am not sure why the page appears at the top again. window.scroll() doesn't do anything without delay. So i am using setTimeout function to scroll the page on the current place. The problem is that in Opera and IE setTimeout takes about 10 ms, so when i click 'Mute' button i see like ticks to top and back. In chrome it takes only 2 ms and there is no problems.
Now when i decide to create my own timeout function the window.scroll() does not work again.
Here is my code:
var isMuted = false;
muteButton.onclick = function() { ////This function works with big delay.
if (!isMuted) {
mainAudio.volume = 0;
isMuted = true;
} else {
mainAudio.volume = bgAudioTrackVolume;
isMuted = false;
}
setTimeout(function() {
window.scroll(0, offset); /// Works
}, 0)
};
Change setTimeout with:
i = 9542155.873; /// I have tried delay time from 1ms - 250ms by changing this value.
while (i > 0.00001) {
i = i / 1.0001234567;
if (i < 0.00001) {
window.scroll(0, offset); /// Does not do anything. Strange! Have tried to change variable with a number.
}
}
Every time i check offset value, it is always available before calling scroll function.
I know that my problem is not usual and i am realy need your help.
The reason that the page scrolls to the top is that you are using a link with the empty bookmark #, which represents the top of the page. The reason that the scroll method doesn't work without a timeout is that jumping to the bookmark happens after the event handler.
Instead of trying to scroll the page back to where it was, just stop the default action of the link by returning false from the event handler:
var isMuted = false;
muteButton.onclick = function() {
if (!isMuted) {
mainAudio.volume = 0;
isMuted = true;
} else {
mainAudio.volume = bgAudioTrackVolume;
isMuted = false;
}
return false;
};
Alternatively, use some other element than a link.

JavaScript: clearInterval won't clear interval

I have an unusual problem. I'm using the following script to check for internet connection using navigator.onLine. If there is internet connection, the page will be refreshed every 15 seconds. If there isn't any internet connection, the page will use innerHTML to display a message.
<script type="text/javascript">
setInterval(function () {
if (navigator.onLine) {
var myInterval = setInterval(function(){window.location.href = "Tracker.html";},15000);
} else {
clearInterval(myInterval);
var changeMe = document.getElementById("change");
change.innerHTML = "<big><font face='Arial' color='#ffffff' size='2'><center>OFFLINE</big><br>No internet connection</font></center>";
}
}, 250);
</script>
My problem is, once there is no internet connection, the message will be displayed, BUT the page would still be refreshed one last time. I'm trying to avoid this, by using clearInterval(myInterval); in the else part of the code, however it won't work.
Any suggestions?
To refresh the page at 15 second intervals (provided that a connection is present), use:
function refresh() {
if(navigator.onLine)
window.location.href = "Tracker.html";
else{
var changeMe = document.getElementById("change");
change.innerHTML = "<big><font face='Arial' color='#ffffff' size='2'><center>OFFLINE</big><br>No internet connection</font></center>";
setTimeout(refresh, 250);
}
}
setTimeout(refresh, 15000);
At the end of 15 seconds, this checks whether a connection is present. If there is, it refreshes the page. If there isn't, it proceeds to check every 250 milliseconds afterwards until the user is reconnected, at which point it refreshes the page.
The net result is that the script refreshes the page as soon as possible after a minimum of 15 seconds have elapsed.
Here is a demonstration: http://jsfiddle.net/JGEt9/show
Whenever the outer interval callback is executed, a new myInterval variable is created and the previous one is lost (it goes out of scope because the callback terminates).
You have to persist the value of the variable between function calls by declaring it outside of the function. You also have to make sure that you are not creating another timeout if one is already running.
var timeout = null;
setInterval(function () {
if (navigator.onLine) {
if (timeout === null) {
timeout = setInterval(function(){window.location.href = "Tracker.html";},15000);
}
} else {
clearTimeout(timeout);
timeout = null;
// ...
}
}, 250);
You need to declare myInterval outside of the if statement. You should only need the refresh code once too. Something like this:
var myInterval = setTimeout(function(){window.location.href = "Tracker.html";},15000);
setInterval(function () {
if (!navigator.onLine) {
clearTimeout(myInterval);
var changeMe = document.getElementById("change");
changeMe.innerHTML = "<big><font face='Arial' color='#ffffff' size='2'><center>OFFLINE</big><br>No internet connection</font></center>";
}
}, 250);
Here you set the refresh interval and continually check to see if the browser is offline, and if it is, you remove the timer and do your cleanup code. I also changed the refresh code to use setTimeout instead of interval because it only happens once.
Another issue is you create changeMe but then try to use change. change doesn't exist. I fixed that in my example as well.
Note: This will not resume refreshing once connection is regained. See Felix Kling's answer.

Using timers (onload)

Ok, firstly, I hardly know Javascript. I really don't know what I'm doing.
So, I have this code:
var interval_id = 0;
var prevent_bust = 0;
// Event handler to catch execution of the busting script.
window.onbeforeunload = function() { prevent_bust++ };
// Continuously monitor whether busting script has fired.
interval_id = setInterval(function() {
if (prevent_bust > 0) { // Yes: it has fired.
prevent_bust -= 2; // Avoid further action.
// Get a 'No Content' status which keeps us on the same page.
window.top.location = 'http://vadremix.com/204.php';
}
}, 1);
function clear ()
{
clearInterval(interval_id);
}
window.onload="setTimeout(clear (), 1000)";
After 1 second I want to clear the interval set earlier. This isn't working. How would I do what I'm trying to do?
If you substitute the last line with window.onload = function() { setTimeout(clear, 1000); }, it should do OK.
There are two errors in your code:
window.onload should be a function, rather than a string ("..."),
setTimeout accepts a function (clear), rather than the result from the function (clear())
By the way, these are some good places to learn JavaScript:
QuirksMode
Mozilla Developer Network

How to automatically reload a page after a given period of inactivity

How can I automatically reload a webpage, if there have been no activity on the page for a given period of time?
This can be accomplished without javascript, with this metatag:
<meta http-equiv="refresh" content="5" >
where content ="5" are the seconds that the page will wait until refreshed.
But you said only if there was no activity, what kind for activity would that be?
If you want to refresh the page if there is no activity then you need to figure out how to define activity. Let's say we refresh the page every minute unless someone presses a key or moves the mouse. This uses jQuery for event binding:
<script>
var time = new Date().getTime();
$(document.body).bind("mousemove keypress", function(e) {
time = new Date().getTime();
});
function refresh() {
if(new Date().getTime() - time >= 60000)
window.location.reload(true);
else
setTimeout(refresh, 10000);
}
setTimeout(refresh, 10000);
</script>
I have built a complete javascript solution as well that does not require jquery. Might be able to turn it into a plugin. I use it for fluid auto-refreshing, but it looks like it could help you here.
JSFiddle AutoRefresh
// Refresh Rate is how often you want to refresh the page
// bassed off the user inactivity.
var refresh_rate = 200; //<-- In seconds, change to your needs
var last_user_action = 0;
var has_focus = false;
var lost_focus_count = 0;
// If the user loses focus on the browser to many times
// we want to refresh anyway even if they are typing.
// This is so we don't get the browser locked into
// a state where the refresh never happens.
var focus_margin = 10;
// Reset the Timer on users last action
function reset() {
last_user_action = 0;
console.log("Reset");
}
function windowHasFocus() {
has_focus = true;
}
function windowLostFocus() {
has_focus = false;
lost_focus_count++;
console.log(lost_focus_count + " <~ Lost Focus");
}
// Count Down that executes ever second
setInterval(function () {
last_user_action++;
refreshCheck();
}, 1000);
// The code that checks if the window needs to reload
function refreshCheck() {
var focus = window.onfocus;
if ((last_user_action >= refresh_rate && !has_focus && document.readyState == "complete") || lost_focus_count > focus_margin) {
window.location.reload(); // If this is called no reset is needed
reset(); // We want to reset just to make sure the location reload is not called.
}
}
window.addEventListener("focus", windowHasFocus, false);
window.addEventListener("blur", windowLostFocus, false);
window.addEventListener("click", reset, false);
window.addEventListener("mousemove", reset, false);
window.addEventListener("keypress", reset, false);
window.addEventListener("scroll", reset, false);
document.addEventListener("touchMove", reset, false);
document.addEventListener("touchEnd", reset, false);
<script type="text/javascript">
var timeout = setTimeout("location.reload(true);",600000);
function resetTimeout() {
clearTimeout(timeout);
timeout = setTimeout("location.reload(true);",600000);
}
</script>
Above will refresh the page every 10 minutes unless resetTimeout() is called. For example:
clicky
Based on the accepted answer of arturnt. This is a slightly optimized version, but does essentially the same thing:
var time = new Date().getTime();
$(document.body).bind("mousemove keypress", function () {
time = new Date().getTime();
});
setInterval(function() {
if (new Date().getTime() - time >= 60000) {
window.location.reload(true);
}
}, 1000);
Only difference is that this version uses setInterval instead of setTimeout, which makes the code more compact.
var bd = document.getElementsByTagName('body')[0];
var time = new Date().getTime();
bd.onmousemove = goLoad;
function goLoad() {
if(new Date().getTime() - time >= 1200000) {
time = new Date().getTime();
window.location.reload(true);
}else{
time = new Date().getTime();
}
}
Each time you move the mouse it will check the last time you moved the mouse. If the time interval is greater than 20' it will reload the page, else it will renew the last-time-you-moved-the-mouse.
use JavaScript setInterval method:
setInterval(function(){ location.reload(); }, 3000);
Auto reload with target of your choice. In this case target is _self set to itself,but you could change the reload page by simply changing the window.open('self.location', '_self'); code to something like this examplewindow.top.location="window.open('http://www.YourPageAdress.com', '_self'";.
With a confirmation ALERT message:
<script language="JavaScript">
function set_interval() {
//the interval 'timer' is set as soon as the page loads
var timeoutMins = 1000 * 1 * 15; // 15 seconds
var timeout1Mins = 1000 * 1 * 13; // 13 seconds
itimer=setInterval("auto_logout()",timeoutMins);
atimer=setInterval("alert_idle()",timeout1Mins);
}
function reset_interval() {
var timeoutMins = 1000 * 1 * 15; // 15 seconds
var timeout1Mins = 1000 * 1 * 13; // 13 seconds
//resets the timer. The timer is reset on each of the below events:
// 1. mousemove 2. mouseclick 3. key press 4. scrolling
//first step: clear the existing timer
clearInterval(itimer);
clearInterval(atimer);
//second step: implement the timer again
itimer=setInterval("auto_logout()",timeoutMins);
atimer=setInterval("alert_idle()",timeout1Mins);
}
function alert_idle() {
var answer = confirm("Session About To Timeout\n\n You will be automatically logged out.\n Confirm to remain logged in.")
if (answer){
reset_interval();
}
else{
auto_logout();
}
}
function auto_logout() {
//this function will redirect the user to the logout script
window.open('self.location', '_self');
}
</script>
Without confirmation alert:
<script language="JavaScript">
function set_interval() {
//the interval 'timer' is set as soon as the page loads
var timeoutMins = 1000 * 1 * 15; // 15 seconds
var timeout1Mins = 1000 * 1 * 13; // 13 seconds
itimer=setInterval("auto_logout()",timeoutMins);
}
function reset_interval() {
var timeoutMins = 1000 * 1 * 15; // 15 seconds
var timeout1Mins = 1000 * 1 * 13; // 13 seconds
//resets the timer. The timer is reset on each of the below events:
// 1. mousemove 2. mouseclick 3. key press 4. scrolling
//first step: clear the existing timer
clearInterval(itimer);
clearInterval(atimer);
//second step: implement the timer again
itimer=setInterval("auto_logout()",timeoutMins);
}
function auto_logout() {
//this function will redirect the user to the logout script
window.open('self.location', '_self');
}
</script>
Body code is the SAME for both solutions:
<body onLoad="set_interval(); document.form1.exp_dat.focus();" onKeyPress="reset_interval();" onmousemove="reset_interval();" onclick="reset_interval();" onscroll="reset_interval();">
I came up with a slightly different solution, because I found that setInterval isn't really accurate, see: setInterval timing slowly drifts away from staying accurate
// Based on https://stackoverflow.com/a/15279599
// Refresh Rate is how often you want to refresh the page
// based off the user inactivity (in seconds).
var refresh_after = 20;
var last_user_action = new Date();
// Reset the Timer on users last action
function reset() {
last_user_action = new Date();
}
// Countdown that executes every second.
setInterval(function () {
refreshCheck();
}, 1000);
// The code that checks if the window needs to reload
function refreshCheck() {
var expire_time = new Date(last_user_action);
expire_time.setSeconds(expire_time.getSeconds() + refresh_after);
now = new Date();
if (now.getTime() >= expire_time.getTime() && document.readyState == "complete") {
window.location.href = window.location.href; // We do this to discard the POST data.
}
}
window.addEventListener("click", reset, false);
window.addEventListener("mousemove", reset, false);
window.addEventListener("keypress", reset, false);
window.addEventListener("scroll", reset, false);
document.addEventListener("touchMove", reset, false);
document.addEventListener("touchEnd", reset, false);
Yes dear,then you have to use Ajax technology. to changes contents of
particular html tag:
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<title>Ajax Page</title>
<script>
setInterval(function () { autoloadpage(); }, 30000); // it will call the function autoload() after each 30 seconds.
function autoloadpage() {
$.ajax({
url: "URL of the destination page",
type: "POST",
success: function(data) {
$("div#wrapper").html(data); // here the wrapper is main div
}
});
}
</script>
</head>
<body>
<div id="wrapper">
contents will be changed automatically.
</div>
</body>
</html>
I would consider activity to be whether or not the user is focused on the window. For example, when you click from one window to another (e.g. Google Chrome to iTunes, or Tab 1 to Tab 2 within an internet browser), the webpage can send a callback saying "Im out of focus!" or "Im in focus!". One could use jQuery to harness this possible lack of activity to do whatever they wanted. If I were in your position, I would use the following code to check for focus every 5 seconds, etc and reload if no focus.
var window_focus;
$(window).focus(function() {
window_focus = true;
}).blur(function() {
window_focus = false;
});
function checkReload(){
if(!window_focus){
location.reload(); // if not focused, reload
}
}
setInterval(checkReload, 5000); // check if not focused, every 5 seconds
And finally the most simple solution:
With alert confirmation:
<script type="text/javascript">
// Set timeout variables.
var timoutWarning = 3000; // Display warning in 1Mins.
var timoutNow = 4000; // Timeout in 2 mins.
var warningTimer;
var timeoutTimer;
// Start timers.
function StartTimers() {
warningTimer = setTimeout("IdleWarning()", timoutWarning);
timeoutTimer = setTimeout("IdleTimeout()", timoutNow);
}
// Reset timers.
function ResetTimers() {
clearTimeout(warningTimer);
clearTimeout(timeoutTimer);
StartTimers();
$("#timeout").dialog('close');
}
// Show idle timeout warning dialog.
function IdleWarning() {
var answer = confirm("Session About To Timeout\n\n You will be automatically logged out.\n Confirm to remain logged in.")
if (answer){
ResetTimers();
}
else{
IdleTimeout();
}
}
// Logout the user and auto reload or use this window.open('http://www.YourPageAdress.com', '_self'); to auto load a page.
function IdleTimeout() {
window.open(self.location,'_top');
}
</script>
Without alert confirmation:
<script type="text/javascript">
// Set timeout variables.
var timoutWarning = 3000; // Display warning in 1Mins.
var timoutNow = 4000; // Timeout in 2 mins.
var warningTimer;
var timeoutTimer;
// Start timers.
function StartTimers() {
warningTimer = setTimeout(timoutWarning);
timeoutTimer = setTimeout("IdleTimeout()", timoutNow);
}
// Reset timers.
function ResetTimers() {
clearTimeout(warningTimer);
clearTimeout(timeoutTimer);
StartTimers();
$("#timeout").dialog('close');
}
// Logout the user and auto reload or use this window.open('http://www.YourPageAdress.com', '_self'); to auto load a page.
function IdleTimeout() {
window.open(self.location,'_top');
}
</script>
Body code is the SAME for both solutions
<body onload="StartTimers();" onmousemove="ResetTimers();" onKeyPress="ResetTimers();">
With on page confirmation text instead of alert
Since this is another method to auto load if inactive I give it a second answer. This one is more simple and easier to understand.
With reload confirmation on the page
<script language="javaScript" type="text/javascript">
<!--
var autoCloseTimer;
var timeoutObject;
var timePeriod = 5100; // 5,1 seconds
var warnPeriod = 5000; // 5 seconds
// Warning period should always be a bit shorter then time period
function promptForClose() {
autoCloseDiv.style.display = 'block';
autoCloseTimer = setTimeout("definitelyClose()", warnPeriod);
}
function autoClose() {
autoCloseDiv.style.display = 'block'; //shows message on page
autoCloseTimer = setTimeout("definitelyClose()", timePeriod); //starts countdown to closure
}
function cancelClose() {
clearTimeout(autoCloseTimer); //stops auto-close timer
autoCloseDiv.style.display = 'none'; //hides message
}
function resetTimeout() {
clearTimeout(timeoutObject); //stops timer
timeoutObject = setTimeout("promptForClose()", timePeriod); //restarts timer from 0
}
function definitelyClose() {
// If you use want targeted reload: parent.Iframe0.location.href = "https://URLHERE.com/"
// or this: window.open('http://www.YourPageAdress.com', '_self');
// of for the same page reload use: window.top.location=self.location;
// or window.open(self.location;, '_self');
window.top.location=self.location;
}
-->
</script>
Confirmation box when using with on page confirmation
<div class="leftcolNon">
<div id='autoCloseDiv' style="display:none">
<center>
<b>Inactivity warning!</b><br />
This page will Reloads automatically unless you hit 'Cancel.'</p>
<input type='button' value='Load' onclick='definitelyClose();' />
<input type='button' value='Cancel' onclick='cancelClose();' />
</center>
</div>
</div>
Body codes for both are the SAME
<body onmousedown="resetTimeout();" onmouseup="resetTimeout();" onmousemove="resetTimeout();" onkeydown="resetTimeout();" onload="timeoutObject=setTimeout('promptForClose()',timePeriod);">
NOTE: If you do not want to have the on page confirmation, use Without confirmation
<script language="javaScript" type="text/javascript">
<!--
var autoCloseTimer;
var timeoutObject;
var timePeriod = 5000; // 5 seconds
function resetTimeout() {
clearTimeout(timeoutObject); //stops timer
timeoutObject = setTimeout("definitelyClose()", timePeriod); //restarts timer from 0
}
function definitelyClose() {
// If you use want targeted reload: parent.Iframe0.location.href = "https://URLHERE.com/"
// or this: window.open('http://www.YourPageAdress.com', '_self');
// of for the same page reload use: window.top.location=self.location;
// or window.open(self.location;, '_self');
window.top.location=self.location;
}
-->
</script>
Using LocalStorage to keep track of the last time of activity, we can write the reload function as follows
function reloadPage(expiryDurationMins) {
const lastInteraction = window.localStorage.getItem('lastinteraction')
if (!lastInteraction) return // no interaction recorded since page load
const inactiveDurationMins = (Date.now() - Number(lastInteraction)) / 60000
const pageExpired = inactiveDurationMins >= expiryDurationMins
if (pageExpired) window.location.reload()
}
Then we create an arrow function which saves the last time of interaction in milliseconds(String)
const saveLastInteraction = () => window.localStorage.setItem('last', Date.now().toString())
We will need to listen to the beforeunload event in the browser to clear our lastinteraction record so we don't get stuck in an infinite reload loop.
window.addEventListener('beforeunload', () => window.localStorage.removeItem('lastinteraction'))
The user activity events we will need to monitor would be mousemove and keypress. We store the last interaction time when the user moves the mouse or presses a key on the keyboard
window.addEventListener('mousemove', saveLastInteraction)
window.addEventListener('keypress', saveLastInteraction)
To set up our final listener, we will use the load event.
On page load, we use the setInterval function to check if the page has expired after a certain period.
const expiryDurationMins = 1
window.addEventListener('load', setInterval.bind(null, reloadPage.bind(null, expiryDurationMins), 1000))
I am doing it like this:
let lastActionTaken = new Date().getTime();
function checkLastAction() {
let now = new Date().getTime();
if (now - lastActionTaken > 1000 * 60 * 60) window.location.reload();
else lastActionTaken = now;
}
window.addEventListener("mousemove", checkLastAction);
window.addEventListener("touchstart", checkLastAction);
window.addEventListener("keydown", checkLastAction);
This will reload the page as soon as the user moves their mouse, hits a key or touches a touchscreen if it has been inactive for 1 hour. Also, this takes care of the focus as well, so if a user is moving their mouse in a different program and then come back to this window it will reload, which is good because the point is to not have old data being shown.
Many of these other answers either don't answer the main part of the question "with no activity", or they are incredibly, unnecessarily complex. I have taken the accepted answer (here: https://stackoverflow.com/a/4644315/9008140 )
and modified it to take advantage of the fact you can assign timers to variables. This allows us to get rid of the second timer, as well as the timestamp.
/**
* create a timer that refreshes the page after the number of
minutes has passed without user interaction.
* Moving the mouse or pressing a key on the current page will start
the timer over.
* #param {any} minutes
*/
var refreshTimer;
function setPageRefreshTimer(minutes) {
var refreshInterval = minutes * 60 * 1000; //interval is in milliseconds. We refresh every x minutes.
$(document.body).bind("mousemove keypress", function (e) {
if (refreshTimer != null && refreshTimer != undefined) {
window.clearTimeout(refreshTimer);
}
refreshTimer = window.setTimeout(function () { window.location.reload(true); }, refreshInterval);
});
refreshTimer = window.setTimeout(function () { window.location.reload(true); }, refreshInterval);
}
This sample code will refresh based on a passed in parameter in minutes, with an accuracy as great as a javascript timer can be. In testing, always less than a second. I created this as a function but you can pull it into your page if you wish.
This task is very easy use following code in html header section
<head> <meta http-equiv="refresh" content="30" /> </head>
It will refresh your page after 30 seconds.

Categories

Resources