user10541587
user10541587

Reputation:

Possibilities of a countdown Timer - Javascript

Is it possible for a countdown timer to be activated whilst in the method of a button and keep running even though a web page is refreshed? I have tried to implement a countdown timer that is activated when a button is clicked but when the web page is refreshed, the timer keeps on running alright but it doesn't show in the web page. So when the user presses the button again, the timer is restarted again including the previous time it left off. Can someone explain? I have posted more than I can count but no one is helping.

Edit; With this code, the timer runs perfectly but doesn't update to the span element when the page is refreshed, button doesn't restart the timer when the timer runs out and it's freaking annoying! Also, the button doesn't remain disabled when the page is refreshed.

https://jsfiddle.net/xLmeagLo/

var button = document.querySelector("#coinbtn1");
var label = document.querySelector("#countdown1");
var timer;
var countdown = localStorage.getItem("countdown") || 60;

button.addEventListener("click", function(e) {
  var uid = firebase.auth().currentUser.uid;
  var coinRef = firebase.database().ref().child('users_coins').child(uid).child('coins');
  var counter = 50;
  coinRef.transaction(function(counter) {
    return (counter || 0) + 50;
  });

  if (!timer) {
    countdown = 10;
    timer = setInterval(function() {
      document.getElementById('coinbtn1').disabled = true;
      countdown--;
      label.innerText = countdown + "s";
      localStorage.setItem("countdown", countdown);
      if (countdown <= 0) {
        clearInterval(timer);
        document.getElementById('coinbtn1').disabled = false;
      }
    }, 1000);
  }
});
<div class="mdl-card__actions mdl-card--border">
  <div>Timer : <span id="countdown1">05:00</span></div>
  <div class="mdl-grid">
    <div class="mdl-layout-spacer"></div>
    <button id="coinbtn1" class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--raised mdl-button--colored">50 coins</button>
    <div class="mdl-layout-spacer"></div>
  </div>
</div>

Upvotes: 0

Views: 349

Answers (3)

Alex
Alex

Reputation: 93

Javascript variables can't persist between page (re)loads, so you need some form of persistence. There's various ways to tackle this depending on your needs:

  • Store in URL - You can make the page take in the countdown goal as a fragment (eg. page.html#20181111-035625 where timestamp goal could be your end time in seconds, miliseconds or as a date-time representation (be careful with : and spaces). When the user presses the button, you re-direct them to the page with the correct fragment added.

    Pros: The goal time can be shared as a URL. Simple to implement. Supported even in ancient browsers, not cleared by clearing local storage / closing the browser.

    Cons: The user only sees the same countdown if they (re)open the same URL, so closing the window and re-navigating to the base page loses the countdown. User can be misled with the wrong countdown by being given the wrong URL


  • SessionStorage or LocalStorage - The former persists until the browser is closed, the later will last through the browser being closed.

    Pros: Not tied to URL. Widely supported on anything relevant (be careful of really old browsers, like IE < 8)

    Cons: Tied to a specific browser/device/origin. If your user opens the page on another device, they will not see their timer.


  • Server-side storage - Store the timer goal / state on some form of persistent backend (database, etc)

    Pros: Persists across devices/browsers/sessions. Most robust as far as the user not being misled with fake timers.

    Cons: Most complex, requires some form of session/account feature on the backend

Upvotes: 1

Frank van Puffelen
Frank van Puffelen

Reputation: 599401

Web pages are stateless. Every time you load a web page, it's as if it's the first time that the browser sees it. So when you reload your page, the browser has no memory of the previous countdown, and all variables are reinitialized.

To make the countdown stateful, you need to store its value between calls. A simple way to do that is to use local storage, which is a key-value store that each web page gets from the browser. You can put a value in it with:

localStorage.setItem('countdown', countdown);

And then get it on reload with:

var countdown = localStorage.getItem('countdown');

A simple example of a countdown timer with this:

var button = document.querySelector("button");
var label = document.querySelector("span");
var timer;
var countdown = localStorage.getItem("countdown") || 60;

button.addEventListener("click", function(e) {
  if (!timer) {
    countdown = 10;
    timer = setInterval(function() {
      countdown--;
      label.innerText = countdown+"s";
      localStorage.setItem("countdown", countdown);
      if (countdown <= 0) {
        clearInterval(timer);
        alert("All done");
      }
    }, 1000);
  }
});
<span>60s</span>
<button>Start countdown</button>

Upvotes: 0

rc_dz
rc_dz

Reputation: 461

you could probably attach that behavior to a new Date() and a variable inside of localStorage. Kind of isTimerActive = true, initialTime = (whenever your button was clicked). and just check update the values on window load (check for isTimerActive, if it is, then update counter based on initialTime + new Date() in whatever unit you need it).

Hope it makes sense

Upvotes: 1

Related Questions