Prevent timer reset on page refresh - javascript

I am in trouble. I did countdown timer code in java script but when I refresh the page timer is reset so how to fix this problem
Here is my code.
var min = 1;
var sec = 59;
var timer;
var timeon = 0;
function ActivateTimer() {
if (!timeon) {
timeon = 1;
Timer();
}
}
function Timer() {
var _time = min + ":" + sec;
document.getElementById("Label1").innerHTML = _time;
if (_time != "0:0") {
if (sec == 0) {
min = min - 1;
sec = 59;
} else {
sec = sec - 1;
}
timer = setTimeout("Timer()", 1000);
} else {
window.location.href = "page2.html";
}
}
<BODY onload="Timer();">
<div id="Label1"> </div>
</BODY>

This approach uses localStorage and does not Pause or Reset the timer on page refresh.
<p id="demo"></p>
<script>
var time = 30; // This is the time allowed
var saved_countdown = localStorage.getItem('saved_countdown');
if(saved_countdown == null) {
// Set the time we're counting down to using the time allowed
var new_countdown = new Date().getTime() + (time + 2) * 1000;
time = new_countdown;
localStorage.setItem('saved_countdown', new_countdown);
} else {
time = saved_countdown;
}
// Update the count down every 1 second
var x = setInterval(() => {
// Get today's date and time
var now = new Date().getTime();
// Find the distance between now and the allowed time
var distance = time - now;
// Time counter
var counter = Math.floor((distance % (1000 * 60)) / 1000);
// Output the result in an element with id="demo"
document.getElementById("demo").innerHTML = counter + " s";
// If the count down is over, write some text
if (counter <= 0) {
clearInterval(x);
localStorage.removeItem('saved_countdown');
document.getElementById("demo").innerHTML = "EXPIRED";
}
}, 1000);
</script>

Javascript is client-sided. It will reset on reload or any other thing.
A simple solution to your problem might be html5 storage, or session storage.
https://www.w3schools.com/html/html5_webstorage.asp
// Store
localStorage.setItem("lastname", "Smith");
// Retrieve
document.getElementById("result").innerHTML = localStorage.getItem("lastname");
Hope this helped!

You're looking for window.localStorage. Something like this should work:
<script language="javascript" type="text/javascript">
var min = 1;
var sec = 59;
var timer;
var timeon = 0;
function ActivateTimer() {
//Don't activate if we've elapsed.
if(window.localStorage.getItem('elapsed') != null)
return;
if (!timeon) {
timeon = 1;
Timer();
}
}
function Timer() {
var _time = min + ":" + sec;
document.getElementById("Label1").innerHTML =_time;
if (_time != "0:0") {
if (sec == 0) {
min = min - 1;
sec = 59;
} else {
sec = sec - 1;
}
timer = setTimeout("Timer()", 1000);
}
else {
window.localStorage.setItem('elapsed', true);
window.location.href = "page2.html";
}
}
</script>

Related

How to keep running my Countdown after a refresh?

I'm learning JS and I'm stuck...
I want to create a countdown (it's done, my countdown is working) who keep running when the page is reloaded.
I used the sessionStorage to "save" the countdown value and also to check if a sessionStorage exists when the page is loaded.
The problem is, I don't know how keep running the countdown with values saved in the sessionStorage.
Could you please help me?
class Timer {
constructor(secondes, minutes) {
this.secondes = secondes;
this.minutes = minutes;
this.button = document.getElementById("button");
this.counter = document.getElementById("counter");
this.storageCheck();
}
countdown(minutes) {
var seconds = this.secondes;
var mins = this.minutes;
var myCounter = this.counter;
function tick() {
var current_minutes = mins-1;
seconds--;
myCounter.innerHTML = current_minutes + ":" + (seconds < 10 ? "0" : "") + seconds;
var duration = sessionStorage.setItem("timer", myCounter.innerHTML);
if( seconds > 0 ) {
setTimeout(tick, 1000);
} else {
if(mins > 1){
countdown(mins-1);
}
}
}
tick();
}
buttonClick() {
button.addEventListener("click", () => {
this.countdown(this.minutes);
})
}
storageCheck() {
if (sessionStorage.getItem("timer")) {
// keep the countdown running
}
}
}
let newTimer = new Timer(60, 20);
newTimer.buttonClick();
<!DOCTYPE html>
<html>
<head>
<title>Test Countdown</title>
</head>
<body>
<div id="counter"></div>
<button id="button">Run</button>
<script type="text/javascript" src="countdown.js"></script>
</body>
</html>
In constructor before initializing secondes and minutes check if they are in the storage.If they dont exists then only set the this.secondes = secondes and this.minutes = minutes;
constructor(secondes, minutes) {
this.button = document.getElementById("button");
this.counter = document.getElementById("counter");
if(!this.storageCheck()){ //check if seconds are mins are stored in storage
this.secondes = secondes; //if not set mins and sec to value passed in constructor
this.minutes = minutes;
}
else{
this.countdown(this.minutes);
}
}
In storage check function , check if the values are there, if there get the values and set to this.secondes and this.minutes and return true else return false
storageCheck() {
//if both mins and secs exists
if (sessionStorage.getItem("mins") &&sessionStorage.getItem("secs")) {
// keep the countdown running
this.minutes=parseInt(sessionStorage.getItem("mins"));//get min
this.secondes=parseInt(sessionStorage.getItem("secs"));//get secs
return true;
}
else
return false;
}
and in countdown funciton save the values to storage
sessionStorage.setItem("mins",vm.minutes);//set current min
sessionStorage.setItem("secs",vm.secondes);//set current sec
Try running this here :https://jsbin.com/bavexigute/1/edit?html,js,console,output
class Timer {
constructor(secondes, minutes) {
this.button = document.getElementById("button");
this.counter = document.getElementById("counter");
if(!this.storageCheck()){ //check if seconds are mins are stored in storage
this.secondes = secondes; //if not set mins and sec to value passed in constructor
this.minutes = minutes;
}
else{
this.countdown();
}
}
countdown() {
debugger;
var vm=this;
if(!(this.minutes-1<0))
this.minutes--;
let tick= function(){
vm.secondes--
if(vm.secondes==0){
vm.secondes=59;
vm.minutes--;
}
vm.counter.innerHTML = vm.minutes + ":" + (vm.secondes < 10 ? "0" : "") + vm.secondes;
if(vm.minutes == 0 && vm.secondes-1==0){
vm.secondes--;
vm.counter.innerHTML = vm.minutes + ":" + vm.secondes-1;
}
else{
setTimeout(tick,1000);
}
sessionStorage.setItem("mins",vm.minutes);//set current min
sessionStorage.setItem("secs", vm.secondes);//set current sec
}
setTimeout(tick,1000);
}
buttonClick() {
button.addEventListener("click", () => {
this.countdown();
})
}
storageCheck() {
//if both mins and secs exists
if (sessionStorage.getItem("mins") && sessionStorage.getItem("secs")) {
// keep the countdown running
this.minutes=parseInt(sessionStorage.getItem("mins"));//get min
this.secondes=parseInt(sessionStorage.getItem("secs"));//get secs
return true;
}
else
return false;
}
}
let newTimer = new Timer(60, 20);
newTimer.buttonClick();
You could use your storage check function to override the minutes and seconds arguments if it exists.
constructor(mins, secs) {
this.mins = mins
this.secs = secs
this.checkStorage = this.checkStorage.bind(this)
this.checkStorage(mins, secs)
}
checkStorage(mins, secs) {
if(window.storage) { // or whatever
this.secs = window.storage.secs
this.mins = window.storage.mins
}
}
Something along those lines. Basically just have the setStorage function change the values that have been set in the constructor.
You can do a simple trick by doing this
window.onload = function() {
let minutes = sessionStorage.getItem("minutes")
let seconds = sessionStorage.getItem("seconds")
let newTimer = new Timer(seconds, minutes);
};
And in sessionStorage instead of storing the whole innerHtml store minutes and seconds hopefully it will solve your problem

In Javascript, I'm using clearInterval() in a function/reset button - the timer resets, but keeps going

I've made a timer with setInterval():
var seconds = 0, minutes = 0;
var timer = document.querySelector("#timer");
var interval = null;
function beginTimer() {
var interval = setInterval(function(){
timer.innerHTML = minutes + " Minute(s) " + seconds + " Seconds";
seconds++;
if(seconds == 60) {
minutes++;
seconds = 0;
}
else if(minutes == 60) {
return "Out of time!";
}
}, 1000);
}
I've set a button in HTML to reset it, but when I use it to clear the timer, it continues running. This is the function with the clearInterval() in it.
function beginGame() {
cards = shuffle(cards);
for (var n = 0; n < cards.length; n++) {
allCards.innerHTML = "";
[].forEach.call(cards, function(item) {
allCards.appendChild(item);
});
cards[n].classList.remove("match", "open", "disable", "show");
}
//resetting values
moves = 0;
counter.innerHTML = moves;
star1.style.visibility = "visible";
star2.style.visibility = "visible";
star3.style.visibility = "visible";
lemon.style.visibility = "hidden";
seconds = 0;
minutes = 0;
clearInterval(interval);
var timer = document.querySelector("#timer");
timer.innerHTML = "0 Minute(s) 0 Seconds";
}
I've been researching this for a couple of days with no luck... could someone kindly help me understand how to stop the timer from continuing to run after reset is initialized? Thanks.
Because you have var interval inside beginTimer, the interval variable inside beginTimer will always reference the local variable, which is distinct from the outer interval (which is never touched). Once beginTimer ends, the local interval variable will simply be garbage collected. Leave off the var to assign to the outer variable instead:
var interval = null;
function beginTimer() {
interval = setInterval(function(){
var intervalinside the beginTimer() is error.
var seconds = 0, minutes = 0;
var timer = document.querySelector("#timer");
var interval = null;
function beginTimer() {
// var interval = setInterval(function(){
interval = setInterval(function(){
timer.innerHTML = minutes + " Minute(s) " + seconds + " Seconds";
seconds++;
if(seconds == 60) {
minutes++;
seconds = 0;
}
else if(minutes == 60) {
return "Out of time!";
}
}, 1000);
}
You need also to reset the ongoing timer before starting a new one. Please try the following:
var interval;
function beginTimer() {
clearInterval(interval);
interval = setInterval(function(){
...

How do I make a HTML count up timer with the days:minutes:seconds without resetting on page refresh?

I only have this code and I would want to make the code in a way that,
it would not reset its timing after I refresh the page, and that all users would see the same count-up timer without the timer resetting on page refresh. Anyone can help? :(
<label id="minutes">00</label>:<label id="seconds">00</label>
<script type="text/javascript">
var minutesLabel = document.getElementById("minutes");
var secondsLabel = document.getElementById("seconds");
var totalSeconds = 0;
setInterval(setTime, 1000);
function setTime() {
++totalSeconds;
secondsLabel.innerHTML = pad(totalSeconds % 60);
minutesLabel.innerHTML = pad(parseInt(totalSeconds / 60));
}
function pad(val) {
var valString = val + "";
if (valString.length < 2) {
return "0" + valString;
} else {
return valString;
}
}
</script>
How about making a small modification to your code using the local storage of your browser.
var minutesLabel = document.getElementById("minutes");
var secondsLabel = document.getElementById("seconds");
// Retrieve the time. If time hasn't been saved it will return null and Number(null) ==> 0
var totalSeconds = Number(window.localStorage.getItem('totalSeconds'));
setInterval(setTime, 1000);
function setTime()
{
//Save the time
window.localStorage.setItem('totalSeconds', ++totalSeconds);
secondsLabel.innerHTML = pad(totalSeconds%60);
minutesLabel.innerHTML = pad(parseInt(totalSeconds/60));
}
function pad(val)
{
var valString = val + "";
if(valString.length < 2)
{
return "0" + valString;
}
else
{
return valString;
}
}

Stop and run again timer via pure javascript

I want to make a simple countdown timer which can be set by + or - and also it can be stopped and run by clicking on itself.
My problem is when it is stopped and then runs it shows NAN for the first number.
I suppose it is because of setTimer function but I don't know how to fix that.Here is my code:
var x = document.getElementsByClassName('session');
var seconds = 60;
var session;
var t;
var on = true;
var minutes = 1;
for (var i = 0; i < x.length; i++) {
x[i].innerHTML = minutes;
}
function increase() {
minutes++;
for (var i = 0; i < x.length; i++) {
x[i].innerHTML = minutes;
}
}
function decrease() {
minutes--;
for (var i = 0; i < x.length; i++) {
if (x[i].innerHTML > 0) {
x[i].innerHTML = minutes;
}
}
}
function setSession() {
session = x[1].innerHTML - 1;
}
function timer() {
if (seconds > 0) {
seconds--;
if (seconds == 0 && session > 0) {
session--;
seconds = 60;
}
}
x[1].innerHTML = session + ':' + seconds;
}
function stoptimer() {
clearInterval(t);
}
function general() {
if (on) {
on = false;
t = setInterval(timer, 100);
} else {
on = true;
stoptimer();
}
}
<div class='session'></div>
<div id='increase' onclick='decrease()'>-</div>
<div id='increase' onclick='increase()'>+</div>
<div class='session' onclick='setSession();general()'></div>
You shouldn't be setting session from the html entity. Basically this creates issues with parsing and could potentially break your code. Also, you subtract one every time you get this value, throwing a spanner in the works.
I re-shuffled your code a bit and added some notes, take a look:
var x = document.getElementsByClassName('session');
var seconds = 0;
var session;
var timer; // give this a useful name
var timerRunning = false; // give this a useful name
var minutes = 1;
function updateMinutes(newMinutes){
if (timerRunning){
return; // do not allow updating of countdown while count down is running
}
if(newMinutes !== undefined){ // allow this function to be called without any parameters
minutes = newMinutes;
}
if(minutes < 1){
minutes = 1; //set your minimum allowed value
}
if(minutes > 99999){
minutes = 99999; //could also have some sort of maximum;
}
for (var i = 0; i < x.length; i++) {
x[i].innerHTML = minutes;
}
session = minutes; // now this can only be set while timer is not running, so no need to get it from the html
//also, i would let this start at the exact same value as minutes, and have seconds start at zero
}
updateMinutes(); // call this now to initialise the display
function increase() {
updateMinutes(minutes + 1);
}
function decrease() {
updateMinutes(minutes - 1);
}
function timer_tick() {
if (seconds > 0) {
seconds--;
if (seconds == -1 && session > 0) { //because of where you've positioned your logic, this should check for negative one, no zero, otherwise you'll never display a zero seconds value
session--;
seconds = 59; //when a timer clocks over it goes to 59
}
}
if (session > 0 || seconds > 0){
x[1].innerHTML = session + ':' + seconds;
}
else{// you need to detect the ending
x[1].innerHTML = "Finished!!";
}
}
function timer_stop() {
clearInterval(timer);
}
function timer_start(){
timer = setInterval(timer_tick, 1000);
}
function timer_toggle() { //give these timer functions consistent names
if (!timerRunning) {
timer_start();
} else {
timer_stop();
}
timerRunning = !timerRunning; //just flip the boolean
}
You set
x[1].innerHTML = session + ':' + seconds;
and then try to calculate that as
session = x[1].innerHTML - 1;
You need to either put the session:seconds in another place or do
session = parseInt(x[1].innerHTML,10) - 1;
Ok, I would propose another approach. Use a class for your timer, like this:
function MyTimer(htmlEl) {
this.sec = 0;
this.min = 0;
this.elt = htmlEl;
}
MyTimer.prototype.set = function(m) {
this.min = m;
this.display();
var self = this;
this._dec = function() {
self.sec--;
if (self.sec < 0) {
if (self.min == 0) {
self.stop();
} else {
self.min -= 1;
self.sec = 59;
}
}
self.display();
}
}
MyTimer.prototype.display = function() {
this.elt.innerHTML = this.min + ":" + this.sec;
}
MyTimer.prototype.toggle = function() {
if (this.interval) {
this.stop();
this.interval = undefined;
} else this.start();
}
MyTimer.prototype.start = function() {
this.interval = setInterval(this._dec, 100);
};
MyTimer.prototype.stop = function() {
clearInterval(this.interval);
};
Then, you can use it like this:
window.onload = init;
var minutes, x, timer;
function init() {
x = document.getElementsByClassName('session');
timer = new MyTimer(x[1]);
minutes = 0;
}
function increase() {
minutes += 1;
x[0].innerHTML = minutes;
timer.set(minutes);
}
function decrease() {
minutes -= 1;
x[0].innerHTML = minutes;
timer.set(minutes);
}
function general() {
timer.toggle();
}
The only change in your html is to remove the setSession call:
<div id='timer' onclick='general()'></div>
This code is more clear. You encapsulate the logic and the min/sec in an object, which is reusable. Here is a working fiddle : https://jsfiddle.net/Shitsu/zs7osc59/.
The origin of your problem is in the code
session = x[1].innerHTML - 1;
Let's re-visit the purpose of keeping of the variable 'session'. I guess it is to keep the value of the maximum value, the upper limit of the minutes, from where to start counting, right? On the other hand, the 'minutes' variable is to keep the temporary value of the minutes. What confused you here is that you've used 'minutes' in place of it's upper limit (what actually is the session's role), in this code for example
function increase() {
minutes++;
for (var i = 0; i < x.length; i++) {
x[i].innerHTML = minutes;
}
}
see, you are updating html by the value of 'minutes', and later you are reading that value into 'session' by that evil code:
session = x[1].innerHTML - 1;
So, why? Why you need to update the value of 'your' variable from html? You should only update the html according to the value of session var and not vice versa. Let's go on and make life simpler...
Let's keep the temporary value of minutes in 'minutes', let's also keep the upper limit in a variable session and, please, let's rename it to maxMinutes. Let's update the 'maxMinutes' only when user clicks '+' or '-' (NEVER from html).
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-1.9.1.min.js"></script>
</head>
<body>
<script>
var x = document.getElementsByClassName('session');
var maxMinutes = 0;
var minutes = maxMinutes;
var seconds = 0;
var timer;
var on = false;
function increase() {
if(on) {
return;
}
maxMinutes++;
minutes = maxMinutes;
x[0].innerHTML = maxMinutes;
x[1].innerHTML = minutes;
}
function decrease() {
if(on) {
return;
}
if(maxMinutes == 0)
{
return;
}
maxMinutes--;
minutes=maxMinutes;
x[0].innerHTML = maxMinutes;
x[1].innerHTML = minutes;
}
function periodicRun() {
if (seconds > 0) {
seconds--;
}
else if(seconds == 0)
{
if(minutes > 0) {
minutes--;
seconds = 60;
}
else
{
stopTimer(timer);
return;
}
}
x[1].innerHTML = minutes + ':' + seconds;
}
function stoptimer() {
clearInterval(timer);
}
function general() {
if (on) {
on = false;
stoptimer();
} else {
on = true;
timer = setInterval(periodicRun, 500);
}
}
$(document).ready(function(){
increase();
});
</script>
<div class='session'></div>
<div id='increase' onclick='decrease()'>-</div>
<div id='increase' onclick='increase()'>+</div>
<div class='session' onclick='general()'></div>
</body>
</html>
Note, that the only place where the maxLimits get's assigned a value is in increase() and decrease(). The 'minutes' and html are in their turn being updated according to maxMinutes.
Good Luck!

Countdown Timer is not showing in javascript

I am new in javascript, I want to create a countdown timer with localStorage which starts from given time and end to 00:00:00, but it's not working,
When I am running my code it is showing value "1506".
Here is my code
<script type="text/javascript">
if (localStorage.getItem("counter")) {
var CurrentTime = localStorage.getItem("counter");
}
else {
var Hour = 3;
var Minute = 25;
var Second = 60;
var CurrentTime = Hour.toString() + ":" + Minute.toString() + ":" + Second.toString();
}
function CountDown() {
document.getElementById('lblDuration').innerHTML = CurrentTime;
Second--;
if (Second == -1) {
Second = 59;
Minute--;
}
if (Minute == -1) {
Minute = 59;
Hour--;
}
localStorage.setItem("counter", CurrentTime);
}
var interval = setInterval(function () { CountDown(); }, 1000);
</script>
you need to declare variables Hour, Minute, Second, CurrentTime out side if else block. In this case they are not in function CountDown() scope.
you are not setting CurrentTime = Hour.toString() + ":" + Minute.toString() + ":" + Second.toString(); after localStorage.setItem("counter", CurrentTime);
var Hour = 3;
var Minute = 25;
var Second = 60;
var CurrentTime = Hour.toString() + ":" + Minute.toString() + ":" + Second.toString();
function CountDown() {
document.getElementById('lblDuration').innerHTML = CurrentTime;
Second--;
if (Second == -1) {
Second = 59;
Minute--;
}
if (Minute == -1) {
Minute = 59;
Hour--;
}
CurrentTime = Hour.toString() + ":" + Minute.toString() + ":" + Second.toString();
}
setInterval(function () {
CountDown();
}, 1000);
<div id="lblDuration"></div>
When localStorage is available you don set the values for Hour, Minute and Second. So when the countdown function executed it finds Second to be undefined and the statement Second-- converts Second to NaN.
To fix it just initialize the Hour, Minute and Second Variable.
I 've refactored your code a little bit hope it helps:
function CountDown() {
var currentTime = getCurrentTime();
printCurrentTime(currentTime)
currentTime.second--;
if (currentTime.second == -1) {
currentTime.second = 59;
currentTime.minute--;
}
if (currentTime.minute == -1) {
currentTime.minute = 59;
currentTime.hour--;
}
setCurrentTime(currentTime);
}
function setCurrentTime(newCurrentTime){
if(localStorage) localStorage.setItem("counter", JSON.stringify(newCurrentTime));
else setCurrentTime.storage = newCurrentTime;
}
function getCurrentTime(){
var result = localStorage ? localStorage.getItem("counter") : setCurrentTime.storage;
result = result || {hour:3, minute:25, second:60};
if (typeof(result) === "string")result = JSON.parse(result);
result.toString = function(){
return result.hour + ":" + result.minute + ":" + result.second;
}
return result;
}
function printCurrentTime(currentime){
var domTag = document.getElementById('lblDuration');
if(domTag) domTag.innerHTML = currentime.toString();
else console.log(currentime);
}
setInterval(function () { CountDown(); }, 1000);

Categories

Resources