0

I am using Java script count down timer for session timeout.

It's working fine for a single tab, but if the page is refreshed or another tab of the same page is opened, the timer resets.

Is there a way to use all the pages from one timer?

Here is my timer code:

var mins = 1;  //Set the number of minutes you need
var secs = mins * 60;
var currentSeconds = 0;
var currentMinutes = 0;
/*
 * The following line has been commented out due to a suggestion left in the comments. The line below it has not been tested.
 * setTimeout('Decrement()',1000);
 */
setTimeout(Decrement, 1000);

function Decrement() {
    currentMinutes = Math.floor(secs / 60);
    currentSeconds = secs % 60;
    if (currentSeconds <= 9) currentSeconds = "0" + currentSeconds;
    secs--;
    document.getElementById("timerText").innerHTML = "Your session remaining(" + currentMinutes + ":" + currentSeconds + ")"; //Set the element id you need the time put into.
    if (secs !== -1) setTimeout('Decrement()', 1000);
}  
vsync
  • 118,978
  • 58
  • 307
  • 400
Taymaz
  • 3
  • 1

3 Answers3

0

You could use the PostMessage API to communicate between windows.
Or you could also use LocalStorage and its "storage" event.

const EL_text = document.getElementById("timerText");
let remaining = 30;
let remainingItv = null;

function Decrement() {  // Just a simplification - example
  remaining -= 1;
  localStorage.remaining = remaining;  // Store the time
}

window.addEventListener("storage", () => {

  EL_text.textContent = localStorage.remaining;    // Use the value here!

  if (localStorage.remaining == "0") {
    localStorage.removeItem("remaining"); // Remove key from localStorage
    clearInterval(remainingItv);
  }
});

// Init!
// Only initiate of there's no "remaining" key inside localStorage
if (undefined === localStorage.remaining) {
  remainingItv = setInterval(Decrement, 1000);
}
Roko C. Buljan
  • 196,159
  • 39
  • 305
  • 313
0

Define your time on the browser's local storage and then it will be available on all tabs/windows

Simply retrieve the timer's value from the localstorage, when a page refreshes, and if it does not exist, create it and save it to the localstorage.

  1. Storing Objects in HTML5 localStorage
  2. localstorage and setInterval() with multiple tabs
  3. communicate between browser tabs with localstorage

You can save the current value (time) of the timer, per tab, to the localStorage every N interval, depending on the timeframe, and then when/if a new tab is opened, it will fetch the "latest" timer's value

vsync
  • 118,978
  • 58
  • 307
  • 400
0

First of all you should never rely on setTimeout() for displaying the time as it is not accurate. They run in a single thread with other operations and they would deviate a lot if other operations take time to complete.

While I am writing this answer, there are already a few good answers posted by different helpful members, but they are just simply link only answers.

One of the common solution is using the help of backend technologies, but apart from the obvious, if you are going to be only relying with the javascript solution, then you will need to write the timestamp to some sort of browser storage or cookies. Then calculate the difference between current time and the initial timestamp to show the session timer.

NOTE: Following example will only work in a hosted environment since it depends on same origin policy. Executing in a developer console won't work.

var startTime;
if (sessionStorage) {
  // Ask other tabs for session storage
  localStorage["getTmestamp"] = "get";

  window.addEventListener("storage", (event) => {
    if (event.key == "getTmestamp") {
      // Some tab asked for the sessionStorage -> send it
      localStorage["timestamp"] = sessionStorage["timestamp"];
      localStorage.removeItem("getTmestamp");
    } else if (event.key == "timestamp" && !sessionStorage["timestamp"]) {
      sessionStorage["timestamp"] = new Date(localStorage["timestamp"]);
      localStorage.removeItem("timestamp");
    }
  });
} else {
  console.warn("Browser doesn't support sessionStorage");
}
var interval = setInterval(() => {
  if (!startTime && sessionStorage && !sessionStorage["timestamp"]) {
    sessionStorage["timestamp"] = new Date();
  }
  startTime = new Date(sessionStorage["timestamp"]);
  var currentTime = new Date();
  var timeElapsed = Math.ceil((currentTime - startTime) / 1000);
  var remainingTime = 30 - timeElapsed;
  if (remainingTime <= 0) {
    console.log("Timeout");
    clearInterval(interval);
  }
  console.log("Session Time in seconds:", timeElapsed);
  console.log("Remaining Session Time in seconds:", remainingTime);
}, 500);
Kiran Shakya
  • 2,521
  • 2
  • 24
  • 37
  • Thank you. But how can I test it? – Taymaz Dec 10 '20 at 15:46
  • @Taymaz A local server like xampp can also serve in localhost or maybe you can add a dummy host to it. If you have access to web hosting, then it will work there as well. The idea is, you should have some domain to pass the same origin policy. – Kiran Shakya Dec 11 '20 at 06:28