How to initialize a countdown timer to reflect the user input - javascript

I'm creating a countdown timer based on a users input. When the user pauses and resumes, the timer restarts at the initial inputed value and fails to resume from the current interval. I've uploaded the code into Codepen.
http://codepen.io/alivera/pen/JGpvRx
//Timer
var myTimer;
var duration = sessionCounter * 60;
var startTimer = function() {
minutes = parseInt(duration / 60);
seconds = parseInt(duration % 60);
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
document.getElementById("clockTimer").innerHTML = minutes + ":" + seconds;
if (--duration < 0) {
document.getElementById("toggleStatus").innerHTML = "<br>Break!";
}
};
//Start Timer
var go = function() {
myTimer = setInterval(startTimer, 1000);
document.getElementById('start').innerHTML = "Stop";
document.getElementById('start').className = "btn btn-danger";
document.getElementById("start").onclick = stop;
};
//Stop Timer
var stop = function() {
clearInterval(myTimer);
document.getElementById('start').innerHTML = "Start";
document.getElementById('start').className = "btn btn-success";
document.getElementById("start").onclick = go;
};
duration.onload = stop();

You're loading the time to count down from from the #clockTimer element:
var sessionCounter = document.getElementById("clockTimer").innerHTML;
This is bad because the contents of that element are changing. Often.
And parseInt on the next line only is only giving you the number before the colon. Your best bet for solving this problem would be storing the current time remaining and the previously set time in separate variables, as I have done below.
Your code was a little difficult to work with, so while correcting the error(s), I ended up almost completely rewriting it.
Here's my version; I'll explain it line-by-line (or section-by-section, or whatever):
First, put all of our elements in to easy-to-use (and type) variables:
var subBreakButton = document.getElementById("subBreakButton"),
breakTimer = document.getElementById("breakTimer"),
addBreakButton = document.getElementById("addBreakButton"),
subSessionButton = document.getElementById("subSessionButton"),
sessionTimer = document.getElementById("sessionTimer"),
addSessionButton = document.getElementById("addSessionButton"),
breakSession = document.getElementById("breakSession"),
clockTimer = document.getElementById("clockTimer"),
These variables are in seconds (thus m * s):
breakLength = 5 * 60, // Minutes to seconds
sessionLength = 25 * 60, // Minutes to seconds
sessionTimeLeft = sessionLength;
Next, a helper method that formats times into a mm:ss ... format:
function timeString (seconds) {
var minutes = parseInt(seconds / 60) + "",
seconds = parseInt(seconds % 60) + "";
if (minutes.length === 1)
minutes = "0" + minutes;
if (seconds.length === 1)
seconds = "0" + seconds;
return minutes + ":" + seconds;
}
Third, event listeners for the plus and minus buttons:
// Event Listeners
addBreakButton.addEventListener("click", function () {
breakLength += 1 * 60;
breakTimer.innerHTML = timeString(breakLength);
});
subBreakButton.addEventListener("click", function () {
breakLength -= 1 * 60;
if (breakLength < 0)
breakLength = 0;
breakTimer.innerHTML = timeString(breakLength);
});
addSessionButton.addEventListener("click", function () {
sessionLength += 1 * 60;
sessionTimer.innerHTML = timeString(sessionLength);
});
subSessionButton.addEventListener("click", function () {
sessionLength -= 1 * 60;
if (sessionLength < 0)
sessionLength = 0;
sessionTimer.innerHTML = timeString(sessionLength);
});
And, the fun part:
// Timer
var myTimer;
function startTimer () {
if (myTimer) // Check to see if a timer was already running, and if so, stop it
stopTimer();
sessionTimeLeft = sessionLength;
myTimer = setInterval(function () {
sessionTimeLeft--;
if (sessionTimeLeft <= 0) {
sessionTimeLeft = 0;
stopTimer();
}
clockTimer.innerHTML = (sessionTimeLeft <= 0? "Break!": timeString(sessionTimeLeft));
}, 1000);
}
function stopTimer () {
clearInterval(myTimer);
myTimer = 0;
}
Lastly, wrappers:
// Start Timer
function go() {
startTimer();
}
//Pause Timer
function stop() {
stopTimer();
}
Codepen: http://codepen.io/anon/pen/ZQjLZE?editors=1010

Related

JavaScript Countdown timer with returned value after every interval

I am trying to write a countdown timer that returns the current countdown value from the function. So far I have managed to write the countdown function. It counts down but the function returns undefined. How can I modify the code to return the countdown value?
const startTimer = (duration, onlySeconds) => {
var timer = duration,
minutes,
seconds;
const interval = setInterval(function () {
minutes = parseInt(timer / 60, 10);
seconds = parseInt(timer % 60, 10);
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
if (timer-- === 0) {
clearInterval(interval)
}
console.log('seconds', seconds)
return !onlySeconds ? minutes + ":" + seconds : seconds;
}, 1000);
};
console.log('You will be logged out in ', startTimer(3, true))
You can't return from the asynchronous setInterval callback and expect to access that returned value. Instead, I might recommend passing a logger function to which you can pass the amount of time remaining. In that function, you can do whatever you want with that time. Here's a version that just does some console logging.
const startTimer = (duration, onlySeconds, logger) => {
var timer = duration,
minutes,
seconds;
const interval = setInterval(function () {
minutes = parseInt(timer / 60, 10);
seconds = parseInt(timer % 60, 10);
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
if (timer-- === 0) {
clearInterval(interval)
}
const time = !onlySeconds ? minutes + ":" + seconds : seconds;
logger(time);
}, 1000);
};
const logger = (time) => {
console.log('You will be logged out in ' + time);
}
startTimer(300, false, logger)
it is much simplier and direct to the point
const startTimer = (duration, onlySeconds) => {
var timer = duration,
minutes,
seconds;
const interval = setInterval(function () {
minutes = parseInt(timer / 60, 10);
seconds = parseInt(timer % 60, 10);
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
if (timer-- === 0) {
clearInterval(interval)
}
console.log('You will be logged out in '+ (!onlySeconds ? minutes + ":" + seconds : seconds));
}, 1000);
};
startTimer(3, true);
I think a different strategy might be in order.
class Countdown {
constructor() {
this._init();
}
_init(restart=false) {
this.target = undefined;
this.running = false;
this.terminate = false;
if(!restart) {
this.ms = undefined;
this.tick = [];
this.done = [];
}
}
// Set a callback that is called every second. `fn(remaining)`
ontick(fn) {
this.tick.push(fn);
}
// Set a callback that is called when the countdown ends. `fn()`
ondone(fn) {
this.done.push(fn);
}
// Start countdown with duration in milliseconds
start(ms) {
const now = performance.now();
if(this.running) throw new Exception('Countdown already running.');
this.running = true;
this.ms = ms;
this.target = now + ms;
this.update = () => {
const now = performance.now();
if(this.terminate) {
this._init();
return;
}
const remaining = this.target - now;
if(remaining > 100) {
setTimeout(this.update, remaining % 1000);
this.tick.forEach(fn => fn(remaining));
}
else {
this.done.forEach(fn => fn());
this._init();
}
};
setTimeout(this.update, this.target % 1000);
}
// Restart a running countdown. Optionally provide a new duration.
restart(ms=this.ms) {
const now = performance.now();
if(!this.running) throw new Exception('Countdown not running.');
this.ms = ms;
this.target = now + ms;
}
// Stop a running countdown.
stop() {
if(!this.running) throw new Exception('Countdown not running.');
this.terminate = true;
}
}
Then you would use it like this:
const countdown = new Countdown();
countdown.ontick(remaining => {
console.log('Remaining:', remaining, 'ms');
});
countdown.ondone(() => {
console.log('Countdown completed.');
});
countdown.start(15*60*1000); // 15 minutes
If you want to restart a running countdown:
countdown.restart(5*60*1000); // Update target duration to 5 minutes and restart
countdown.restart(); // Use previous duration and restart
If you want to cancel the countdown:
countdown.stop();

Adding time on button click to a count down timer

Im creating a countdown timer which starts at 3mins and 30secs.
When the timer reaches 0 the initial 3:30 timer will be repeated.
This happens until the user presses a button, which will add 1:45 to the timer and pause the timer until the user decides to resume the timer from the new value. Eg ( 3:30 + 1:45 = 5:15).
Now I have got the first 2 step to work with my current code, but I'm having a lot of issues with the 3rd part. Once the user clicks the add 1.45 button the count works, but only up until a certain point. After this point it will start to display a negative integer.
I'm sure there is an easier way to write this code. I have really overcomplicated this. Any suggestions would be appreciated.
//Define vars to hold time values
let startingMins = 3.5;
let time = startingMins * 60;
//define var to hold stopwatch status
let status = "stopped";
//define var to holds current timer
let storeTime = null;
//define Number of sets
let setNum = 1;
//Stop watch function (logic to determin when to decrement each value)
function stopwatch () {
minutes = Math.floor(time / 60);
let seconds = time % 60;
seconds = seconds < 10 ? '0' + seconds : seconds;
storeTimer = minutes + ":" + seconds; //Store time in var
storeTime = minutes + "." + seconds; //Store time in var
//Display updated time values to user
document.getElementById("display").innerHTML = storeTimer;
time--;
// When timer reachers 0 secs the inital 3:30 countdown will begin again.
if (time <= 0) {
startingMins = 3.5;
time = startingMins * 60;
minutes = Math.floor(time / 60);
seconds = time % 60;
seconds = seconds < 10 ? '0' + seconds : seconds;
setNum++;
//console.log(setNum);
}
}
function StartStop() {
if(status === "stopped") {
//start watch
interval = window.setInterval(stopwatch, 100);
var startButton = document.getElementById("start");
document.getElementById("start").innerHTML = "Pauce";
//startButton.style.display = "none"
status = "start";
//console.log(time);
}
else {
window.clearInterval(interval);
document.getElementById("start").innerHTML = "Start";
status = "stopped";
console.log(storeTime);
}
}
function pauceAdd () {
if(status === "stopped") {
//start watch
interval = window.setInterval(stopwatch, 1000);
var zukButton = document.getElementById("pauceAdd");
status = "start";
}
else {
window.clearInterval(interval);
status = "stopped";
console.log("store time " + storeTime);
let time = +storeTime + +1.45; //store time is 3.30 adding 4.75
console.log("store time2 " + time); // correct result 4.75
minutes = Math.floor(time);/// convert time from Mins (4.75) to seconds (475)
let seconds = time % 60; // 5
if (seconds < 60 ) { // if the Stored time is greater than 60 secs add 1 minute to the timer
minutes++;
seconds = seconds * 100;
console.log("secs updated = " + seconds ); // seconds updated (475)
if (seconds <= 460) {
seconds = Math.floor(seconds - 460);
console.log("seconds 2 == " + seconds)
}
else if (seconds > -60) { // Stuck here
seconds = seconds + 60;// Stuck here
}// Stuck here
else {
seconds = Math.floor(seconds - 460);
console.log("seconds 2 = " + seconds)
}
}
if (seconds < 1) {
seconds = seconds + 60;
minutes = minutes - 1;
}
seconds = seconds < 10 ? + seconds : seconds;
console.log("mins updated = " + minutes + "__________________________-");
//Display updated time values to user
document.getElementById("display").innerHTML = minutes + ":" + seconds;
}
}
function reset () {
//window.clearInterval(storeTime);
window.clearInterval(interval);
startingMins = 3.5;
time = startingMins * 60;
minutes = Math.floor(time / 60);
seconds = time % 60;
seconds = seconds < 10 ? '0' + seconds : seconds;
status = "stopped";
setNum = 1;
var startButton = document.getElementById("start");
startButton.style.display = "inline-block";
document.getElementById("display").innerHTML = "3:30";
document.getElementById("start").innerHTML = "Start";
}
I might have taken the requirements a bit too literally:
Im creating a countdown timer which starts at 3mins and 30secs.
When the timer reaches 0 the initial 3:30 timer will be repeated.
This happens until the user presses a button, which will add 1:45 to the timer and pause the timer until the user decides to resume the
timer from the new value. Eg ( 3:30 + 1:45 = 5:15).
There's a trick to countdown timers. You have to use timestamps to find out how much time ACTUALLY elapsed. You can't trust that your interval will fire exactly every second. In fact, it almost always fires a bit later (in my tests, about 2-3 milliseconds, but I was logging to the console as well, so that might have skewed the test).
let interval, timestamp;
let countdown = 210000;
document.addEventListener("DOMContentLoaded", () => {
document
.querySelector("button")
.addEventListener("click", (event) => toggleState(event.target));
});
function toggleState({ dataset }) {
timestamp = Date.now();
if (dataset.state == "running") {
clearInterval(interval);
countdown += 105000;
updateDisplay(dataset, "paused");
} else {
interval = setInterval(() => updateCountdown(dataset), 100);
updateDisplay(dataset, "running");
}
}
function updateCountdown(dataset) {
const now = Date.now();
countdown -= now - timestamp;
if (countdown <= 0) countdown = 210000;
timestamp = now;
updateDisplay(dataset, "running");
}
function updateDisplay(dataset, label) {
dataset.state = label;
dataset.time = `(${new Date(countdown).toISOString().slice(14, 19)})`;
}
button::before {
content: attr(data-state);
}
button::after {
content: attr(data-time);
padding-left: 0.5em;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/skeleton/2.0.4/skeleton.min.css" rel="stylesheet" />
<button data-state="stopped" data-time="(03:30)"></button>

Countdown timer - make it persistent even after refresh or reload

I have a html page where there is counter starts on page loading. But the problem is if someone refresh or reloads the page the counter restarts. I dont know how to use local storage or cookies to make sure my counter does not reset upon reload. I am aware of the similar questions available here but my issue is i want local storage to be part of a function (countDown()).
Here is the code I tried:
<script>
var timer;
function countDown(i, callback) {
//callback = callback || function(){};
timer = setInterval(function() {
minutes = parseInt(i / 60, 10);
seconds = parseInt(i % 60, 10);
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
document.getElementById("displayDiv ").innerHTML = "Time (h:min:sec) left for this station is " + "0:" + minutes + ":" + seconds;
i-- || (clearInterval(timer), callback());
}, 1000);
}
window.onload = function() {
countDown(60, function() {
$('#myModal').modal('show');
});
};
</script>
First, persist your current counter value to the session storage (with a specific key) at each iteration. You may only persist/update the value when the counter is greater than 0, and then clear the storage key once counter reached 0.
const COUNTER_KEY = 'my-counter';
function countDown(i, callback) {
//callback = callback || function(){};
timer = setInterval(function() {
minutes = parseInt(i / 60, 10);
seconds = parseInt(i % 60, 10);
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
document.getElementById("displayDiv").innerHTML = "Time (h:min:sec) left for this station is " + "0:" + minutes + ":" + seconds;
if ((i--) > 0) {
window.sessionStorage.setItem(COUNTER_KEY, i);
} else {
window.sessionStorage.removeItem(COUNTER_KEY);
clearInterval(timer);
callback();
}
}, 1000);
}
Then on the window.onload function, first check if there is a value under the above key on the session storage. If a value is there, start the countdown from that value. Otherwise, start from your default value (60).
window.onload = function() {
var countDownTime = window.sessionStorage.getItem(COUNTER_KEY) || 60;
countDown(countDownTime, function() {
$('#myModal').modal('show');
});
};
You can try using localStorage as follows:
var timer;
function countDown(i, callback) {
//callback = callback || function(){};
timer = setInterval(function () {
minutes = parseInt(i / 60, 10);
seconds = parseInt(i % 60, 10);
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
document.getElementById("displayDiv").innerHTML = "Time (h:min:sec) left for this station is " + "0:" + minutes + ":" + seconds;
// update the persisted time interval
localStorage.setItem('timeLeft', i);
i-- || (clearInterval(timer), callback());
}, 1000);
}
window.onload = function () {
let timeInterval = 100;
//check if you have the last counter value
let timeLeft = localStorage.getItem('timeLeft');
if (isNaN(timeLeft)) {
//save the current interval
localStorage.setItem('timeLeft', timeInterval);
} else if (timeLeft == 0) {
//save the current interval
localStorage.setItem('timeLeft', timeInterval);
} else {
// take the last saved value
timeInterval = timeLeft;
}
countDown(timeInterval, function () {
$('#myModal').modal('show');
});
};
I think what you want is a property called sessionStorage which stores information in the browser permanently.
here's a link explaining it
https://www.w3schools.com/jsref/prop_win_sessionstorage.asp
I have a made a promise based function for this.
It uses localStorage to store the countdown every 1 second and, once the time is over, it returns you a promise.
I use it with React and React Router on production, it's been working great.
function countdown(interval = 5000) {
return new Promise(async (resolve, reject) => {
let intervalLoop = null
function countTimer() {
if (!localStorage.endTime) {
localStorage.endTime = +new Date() + interval
}
let remaining = localStorage.endTime - new Date()
if (remaining >= 0) {
let currentTime = Math.floor(remaining / 1000)
console.log("Countdown current time:", currentTime)
} else {
clearInterval(intervalLoop)
resolve(true)
}
}
intervalLoop = setInterval(countTimer, 1000)
})
}
Make sure you are inside an async function to use it:
(async _ => {
console.log("Countdown starts now...")
await countdown(5000)
console.log("Countdown is over!");
})()

Javascrip count down timer: prevent reseting on page reload

I have a minute timer which counts from 15 to 0. I don't want to reset (= restart) the timer on page reload. but I can't figure out how to prevent the timer from resetting on a page reload. I'm using javascript with php. I have tried to add the timer time on load to php session but that didn't work for me. any suggestions? thank you :)
function startTimer() {
setTimeout('timer()', 60);
}
var continueMins = localStorage.getItem("continueMins");
var continueSecs = localStorage.getItem("continueSecs");
if (continueMins == 'true') {
mins = continueMins;
} else {
mins = 15;
}
if (continueSecs == 'true') {
secs = continueSecs;
} else {
secs = mins * 60;
}
function timer() {
if (document.getElementById) {
minutes = document.getElementById("minutes");
seconds = document.getElementById("seconds");
progressBar = document.getElementById("progressBar");
timerContainer = document.getElementById("timer-container");
expired = document.getElementById("expired");
btcAmount = document.getElementById("btcAmount");
btcAddress = document.getElementById("btcAddress");
window.onbeforeunload = function() {
localStorage.setItem("continueMins", getMinutes());
localStorage.setItem("continueSecs", getSeconds());
}
var totalSeconds = 15 * 60, remainingSeconds = getMinutes() * 60 + getSeconds();
progressBar.style.width = (remainingSeconds * 100 / totalSeconds) + "%";
minutes.innerHTML = getMinutes() < 10 ? "0" + getMinutes() : getMinutes();
seconds.innerHTML = getSeconds() < 10 ? "0" + getSeconds() : getSeconds();
if (mins < 1) {
minutes.classList.add("text-danger");
seconds.classList.add("text-danger");
}
if (mins < 0) {
expired.style.display = 'block';
timerContainer.style.display = 'none';
btcAmount.text = 'Expired';
btcAddress.text = 'Payment Window Expired';
localStorage.removeItem("continueMins");
localStorage.removeItem("continueSecs");
} else {
secs--;
setTimeout('timer()', 1000);
}
}
}
function getMinutes() {
mins = Math.floor(secs / 60);
return mins;
}
function getSeconds() {
return secs - Math.round(mins * 60);
}
startTimer();
<p class="font-18 font-500"><span id="minutes"></span> : <span id="seconds"></span></p>
You could use the localStorage (sessionStorage is also an option but more prone to restart your timer if the user e.g. reconnects in a new tab or restarts the browser)
How to do it to be on the save side (crashes, unexpected bahaviour e.g.you should update the elapsed time in your local storage from time to time. The "normal" situations are handled by checking for the respective event:
var aTimer, bool;
window.onbeforeunload = function (e) {
if (bool) return;
aTimer = setTimeout(function () {
bool = true;
localStorage.setItem("resetTimer", "false");
localStorage.setItem("currentTimer", MY_TIMER_VAR);
localStorage.setItem("sessionDate", MY_NEW_SESSION_VAR);
}, 500);
return ;
};
EDIT If you want that an elapsed timer is valid for lets say 24 hours you have also to place MY_NEW_SESSION_VAR which is a Date.now() converted in hours when reloading you check against TODAY_DATETIME_IN_HOURS which is a Date.now() converted in hours (This was my use case, if you do not need it just leave it out)
The keys and the values are always strings (note that, as with objects, integer keys will be automatically converted to strings).
When starting your program (loading js) you should check for the vars with:
var resetTimer = localStorage.getItem("resetTimer");
var sessionDate = localStorage.getItem("sessionDate");
if (resetTimer == "true" || sessionDate > (TODAY_DATETIME_IN_HOURS - 24) ){ // start timer }
To delete a single item
localStorage.removeItem("sessionDate");
If you want to use sessionStorage just replace localStorage with sessionStorage
EDIT full code for the OP tested and working as asked
var countDownTarget;
if (document.readyState!="loading") docReady();
/* Modern browsers */
else document.addEventListener("DOMContentLoaded", docReady);
function docReady() {
countDownTarget = parseInt(localStorage.getItem("countDownTarget"));
console.debug("Initvalue: " + countDownTarget);
if (isNaN(countDownTarget) == true || countDownTarget == "" || countDownTarget <= 0){ // If not defined
countDownTarget = new Date().getTime() + 15 * 60 * 1000;
console.debug("is NaN sInitvalue: " + countDownTarget);
//Update the count down every 1 second
setInterval(countDown, 1000);
} else {
console.debug("else Initvalue: " + countDownTarget);
setInterval(countDown, 1000);
}
}
window.onbeforeunload = function() {
localStorage.setItem("countDownTarget", countDownTarget);
};
// Functions you call
function countDown(){
var now = new Date().getTime();
//console.debug("now " + now);
var distance = countDownTarget - now;
console.debug("distance " + distance);
var mins = distance < 0 ? 0 : Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var secs = distance < 0 ? 0 : Math.floor((distance % (1000 * 60)) / 1000);
/** Add a zero in front of numbers<10 */
mins = prependZero(mins);
secs = prependZero(secs);
// Output the results
document.getElementById("minutes").innerHTML = mins;
document.getElementById("seconds").innerHTML = secs;
if (distance <= 0) {
// clearInterval(x);
localStorage.removeItem("countDownTarget");
clearInterval(countDown);
}
}
function prependZero(i){
if (i < 10) {
i = "0" + i;
}
return i;
}
Copy between your script tags or load as *.js file

Minutes not quite in sync with seconds

I have a timer which I am testing, it seems there is a bit of drift between when the minute countdown goes down by 1 and seconds whenever it reaches 59 seconds ()ie every minute:-
How can I alter this so they are both in sync?
my code is the following:-
$(document).ready(function() {
function now() {
return window.performance ? window.performance.now() : Date.now();
}
function tick() {
var timeRemaining = countdown - ((now() - initTick) / 1000);
timeRemaining = timeRemaining >= 0 ? timeRemaining : 0;
var countdownMinutes = Math.floor(timeRemaining / 60);
var countdownSeconds = timeRemaining.toFixed() % 60;
countdownTimer.innerHTML = countdownMinutes + ":" + countdownSeconds;
if (countdownSeconds < 10) {
countdownTimer.innerHTML = countdownMinutes + ":" + 0 + countdownSeconds;
}
if (timeRemaining > 0) {
setTimeout(tick, delay);
}
}
var countdown = 600; // time in seconds until user may login again
var delay = 20; // time (in ms) per tick
var initTick = now(); // timestamp (in ms) when script is initialized
var countdownTimer = document.querySelector(".timer"); // element to have countdown written to
setTimeout(tick, delay);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<div class="timer"></div>
js fiddle: https://jsfiddle.net/robbiemcmullen/cer8qemt/1/
The issue is the precision is not the same for minutes and seconds.
You need to round to the nearest second before /60 / %60.
Consider: exactly 9 mins remaining:
var x = 540;
console.log(x.toFixed() % 60, Math.floor(x / 60));`
Output is: (0,9)
Then consider the call 20 ms later:
var x = 539.980;
console.log(x.toFixed() % 60, Math.floor(x / 60));
the output is now: (0, 8).
So the seconds haven't changed (yet) but the minute does.
Here is a version using setInterval and removing the use of .toFixed ()
Why do you use an interval of 20ms and not 1 second?
//method for countdown timer
$(document).ready(function() {
function now() {
return window.performance ? window.performance.now() : Date.now();
}
function tick() {
var timeRemaining = countdown - elapsedTime;
var countdownMinutes = Math.floor(timeRemaining / 60);
var countdownSeconds = timeRemaining % 60;
countdownTimer.innerHTML = countdownMinutes + ":" + countdownSeconds;
if (countdownSeconds < 10) {
countdownTimer.innerHTML = countdownMinutes + ":" + 0 + countdownSeconds;
}
++elapsedTime;
return timeRemaining;
}
var countdown = 600;
var elapsedTime = 0;
var timeRemaining;
// countdown: time in seconds until user may login again
//var delay = 20;
// delay: time (in ms) per tick
var initTick = now(); // initTick: timestamp (in ms) when script is initialized
var countdownTimer = document.querySelector(".timer");
// countdownTimer: element to have countdown written to
var interval = setInterval(function() {
if(tick() <= 0) {
clearInterval(interval);
}
}, 1000);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="timer"></div>
js fiddle https://jsfiddle.net/ud3wm8t1/

Categories