Javascript timer not displaying? - javascript

I'm trying to build a simple timer using JS. So far, I have:
var ms = 1500000;
var refresh = setInterval(function(){
ms -= 1000;
var minutes = Math.floor((ms / 1000 / 60));
var seconds = Math.floor((ms / 1000) % 60);
return {
'minutes': minutes,
'seconds': seconds
};
},1000);
$(document).ready(function() {
$('#minutes').html(refresh().minutes);
$('#seconds').html(refresh().seconds);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<div id="minutes"></div>
<div id="seconds"></div>
I can't figure out why the minutes and seconds aren't showing up when I preview the html file in Chrome. I suspect I'm calling the object wrong, but I'm not sure what I should change refresh.minutes and refresh.seconds to.

setInterval does not return the result of the function you pass to it. It returns an ID of the timer that can be used to stop it. You can
set HTML within the function you pass to setInterval (and start timer when document ready) or
store minutes and seconds in global variables
as examples how to make it work.

const start = Date.now();
const target = Date.now() + 1*3600*1e3;
const timeLeft = () => {
const left = target - Date.now();
if (left < 0) return false;
return {
min: Math.floor(left/60e3),
sec: Math.floor((left/1e3)%60)
};
};
let i; // for setInterval handler
const update = () => {
let data = timeLeft();
if (!data) {
// stop the timer
clearInterval(i);
return;
}
$('#minutes').text(data.min);
$('#seconds').text(data.sec);
};
// save setInterval result for ability to stop the timer
i = setInterval(update, 1000);
update();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<span id="minutes">0</span>:<span id="seconds">0</span>

setInterval Always returns an id. It is not a regular function which can return a value of user's choice.
The best way to achieve what you need is to directly update your html from inside your interval function.
var ms = 1500000;
$(document).ready(function() {
setInterval(function(){
ms -= 1000;
var minutes = Math.floor((ms / 1000 / 60));
var seconds = Math.floor((ms / 1000) % 60);
$('#minutes').html(minutes);
$('#seconds').html(seconds);
},1000);
});

Related

seeking explanation for timer tutorial

Hi everyone I am new to JavaScript and was watching some tutorials on the stopwatch in javascript I manage to understand most of the code but still have some questions. I was wondering can someone help explain the purpose of the interval being null. and how did this code work? how did it prevent the function starts
// Global variables
const time_el = document.querySelector('.watch .time');
const start_btn = document.getElementById('start');
const stop_btn = document.getElementById("stop");
const reset_btn = document.getElementById("reset");
let seconds = 0;
let interval = null;
// Event listeners
start_btn.addEventListener('click', start);
stop_btn.addEventListener("click", stop);
reset_btn.addEventListener("click", reset);
// Update the timer
function timer() {
seconds++;
// Format our time
let hrs = Math.floor(seconds / 3600);
let mins = Math.floor((seconds - (hrs * 3600)) / 60);
let secs = seconds % 60;
if (secs < 10) secs = '0' + secs;
if (mins < 10) mins = "0" + mins;
if (hrs < 10) hrs = "0" + hrs;
time_el.innerText = `${hrs}:${mins}:${secs}`;
}
function start() {
if (interval) {
return
}
interval = setInterval(timer, 1000);
}
function stop() {
clearInterval(interval);
interval = null;
}
function reset() {
stop();
seconds = 0;
time_el.innerText = '00:00:00';
}
<div class="watch">
<div class="time"></div>
</div>
<button id="start">start</button>
<button id="stop">stop</button>
<button id="reset">reset</button>
from running again when I clicked more than once?
function start () {
if (interval) {
return
}
interval = setInterval(timer, 1000);
}
I pasted the whole JS code to give a better context
In javascript null evaluates to false (falsy values): js-falsy, there are also values that evaluate to true (truthy values): js-truthy, so they initialize the variable interval to null so the code knows whether to start the timer, if it doesn't evaluate to false (falsy) the timer has been started and setInterval has been called, so it returns immediately on another click of the start button.
setInterval returns an Interval ID which is a unique identifier: setInterval, this is what is stored in interval on initial start button click, so on subsequent clicks, the variable interval evaluates to true (truthy).
Added a code snippet to demonstrate what I tried to describe in points 1 and 2.
let interval = null;
//Check to see if interval evaluates to false(falsy)
if(!interval){
console.log("interval evaluated to false(falsy)");
}
//set interval to the ID of call to setInterval()
interval = setInterval(() => {
console.log("setInterval() called and interval set to my ID");
}, 1000000);
//Check to see if interval evaluates to true(truthy)
if(interval){
console.log("setInterval ID: " + interval);
console.log("interval evaluated to true(truthy)");
}

Multiple consecutive 5 minute countdown timers

I want to make 3 countdown timers where the next one starts when the last one ends (the first timer will start counting down the time automatically, but the second timer will only start when the first one reaches 0:00 and the third one will only start when the second one reaches 0:00).
I found this code for a countdown timer:
function countDown() {
var seconds = 60;
var mins = 5;
function clickClock() {
var counter = document.getElementById("countdown1");
var currentMinutes = mins - 1;
seconds--;
counter.innerHTML = currentMinutes.toString() + ":" + (seconds < 10 ? "0" : "") + String(seconds);
if(seconds > 0) {
setTimeout(clickClock, 1000);
} else {
if(mins > 1) {
countDown(mins-1);
}
}
}
clickClock();
}
countDown();
On my HTML, I have 3 spans, each with a unique ID (#countdown1, #countdown2, #countdown3)
I have tried passing in an parameter to the clickClock() function called counter so that whenever I called the function I could enter the id of the element I wanted to affect, didn't work.
I could just make 2 other functions that would do exactly the same thing but would change the counter variable, but I'd like to avoid repeating unnecessary things in my code.
How could this be done?
Any help is appreciated :)
I'd do something like this:
/////////// USAGE
const timersDurationInMilliseconds = 1000 * 5; // for 5 minutes do: 1000 * 60 * 5
// Render initial timer content
RenderTimer('countdown1', timersDurationInMilliseconds);
RenderTimer('countdown2', timersDurationInMilliseconds);
RenderTimer('countdown3', timersDurationInMilliseconds);
// Start countdown, then start another ones
countDown(timersDurationInMilliseconds, 'countdown1')
.then(() => countDown(timersDurationInMilliseconds, 'countdown2'))
.then(() => countDown(timersDurationInMilliseconds, 'countdown3'))
.then(() => alert('All timers finished!'));
/////////// REQUIRED METHODS
function countDown(durationInMilliseconds, elementId) {
return new Promise((resolve, reject) => {
const updateFrequencyInMilliseconds = 10;
const currentTimeInMilliseconds = new Date().getTime();
const endTime = new Date(currentTimeInMilliseconds + durationInMilliseconds);
function updateTimer(elementId) {
let timeLeft = endTime - new Date();
if (timeLeft > 0) {
// We're not done yet!
setTimeout(updateTimer, updateFrequencyInMilliseconds, elementId);
} else {
// Timer has finished!
resolve();
// depending on update frequency, timer may lag behind and stop few milliseconds too late
// this will cause timeLeft to be less than 0
// let's reset it back to 0, so it renders nicely on the page
timeLeft = 0;
}
RenderTimer(elementId, timeLeft);
}
updateTimer(elementId);
});
}
function padNumber(number, length) {
return new String(number).padStart(length || 2, '0'); // adds leading zero when needed
}
function RenderTimer(elementId, timeLeft) {
const hoursLeft = Math.floor(timeLeft / 1000 / 60 / 60 % 60);
const minutesLeft = Math.floor(timeLeft / 1000 / 60 % 60);
const secondsLeft = Math.floor(timeLeft / 1000 % 60);
const millisecondsLeft = timeLeft % 1000;
const counterElement = document.getElementById(elementId);
counterElement.innerHTML = `${padNumber(hoursLeft)}:${padNumber(minutesLeft)}:${padNumber(secondsLeft)}.${padNumber(millisecondsLeft, 3)}`;
}
<p>First countdown: <span id="countdown1"></span></p>
<p>Second countdown: <span id="countdown2"></span></p>
<p>Third countdown: <span id="countdown3"></span></p>
If you want to only display minutes and seconds, you can adjust that behavior in RenderTimer method.
If you don't plan on displaying milliseconds to the user, you may want to change how frequent the timer is updated and rendered on the page by adjusting the updateFrequencyInMilliseconds variable (e.g. from 10ms to 1000ms).

reset timer back to 0 by using the timer setInterval/clearInterval for stopwatch

Im working on code for a simple stopwatch. Last obstacle for me is reset the time to zero. The function resetTimer is where i am trying to implement the code. So the webpage will display a page with a timer and three buttons; stop, start and reset. When a user clicks the reset button, the timer is supposed to reset back to zero. I have been having trouble trying to make it work. Any help/ideas would be clutch.
I hope i made myself clear. Again i am trying to make the timer reset to 00:00:00
window.onload = function () {
//grab possible elements needed
const timerEl = document.getElementById("timer-text")
const startBtn = document.getElementById("start")
const restartBtn = document.getElementById("restart");
const stopBtn = document.getElementById('stop');
//hold variables of time and set to 0
let hours = parseInt('0');
let minutes = parseInt('0');
let seconds = parseInt('0');
let time;
function makeTwoNumbers(num) {
if (num < 10) {
return "0" + num
}
return num
}
//timer
let timer = () => {
seconds++
//console.log(seconds)
if (seconds == 60) {
minutes++
seconds = 0;
hours = 0
}
if (minutes == 60) {
hours++
minutes = 0;
hours = 0;
}
timerEl.textContent = makeTwoNumbers(hours)+ ": " + makeTwoNumbers(minutes) + ": " + makeTwoNumbers(seconds);
}
let runTheClock;
//timer is running
function runTimer() {
runTheClock = setInterval(timer, 20);;
}
function stopTimer() {
clearInterval(runTheClock)
}
//function will reset timer
function resetTimer() {
time--;
timerEl.textContent;
if (time === 0) {
stopTimer();
time = 0
}
}
restartBtn.addEventListener("click", function () {
resetTimer();
})
//button will pause the timer
stopBtn.addEventListener("click", function () {
stopTimer();
})
//button will start the timer
startBtn.addEventListener("click", function () {
runTimer();
})
}
Here's a fixed and slightly refactored version.
<html>
<body>
<div id="timer-text"></div>
<button id="start">start</button>
<button id="restart">restart</button>
<button id="stop">stop</button>
</body>
<script>
const timerEl = document.getElementById("timer-text")
const startBtn = document.getElementById("start")
const restartBtn = document.getElementById("restart");
const stopBtn = document.getElementById('stop');
let runTheClock;
let seconds = 0;
render(seconds);
function makeTwoNumbers(num) {
return ((num < 10) ? "0" : "") + num;
}
function tick() {
seconds++;
render(seconds);
}
function render(secs) {
const hours = Math.floor(secs / 3600);
const minutes = Math.floor(secs / 60) - (hours * 60);
const seconds = secs % 60;
const val = [hours, minutes, seconds].map(makeTwoNumbers).join(":");
console.log(val);
timerEl.textContent = val;
}
function runTimer() {
runTheClock = setInterval(tick, 1000);
}
function stopTimer() {
clearInterval(runTheClock)
}
function resetTimer() {
seconds = 0;
render(seconds);
}
restartBtn.addEventListener("click", resetTimer);
stopBtn.addEventListener("click", stopTimer);
startBtn.addEventListener("click", runTimer);
</script>
</html>
In the reset function it just sets seconds back to 0 and sets the textContent value so it appears on the page. I separated out the calculating and drawing of the time into a render fucntion, so it can be reused whenever it needs to be re-rendered.
To explain the render function.
We only need to store the number of seconds as a persistent variable between the periodic function calls. We can derive hours and minutes from it. This makes it much less error prone than trying to increment hours and minutes as well.
To calculate hours we just divide seconds by 3600 (or 60 x 60 the number of seconds in an hour) and round down.
To calculate minutes we can calculate the number of total minutes (seconds / 60 and round down) then subtract the number of minutes in the hours value we calculated (hours * 60).
For seconds we use modulus or % which is just a fancy word for remainder. So seconds % 60 gives us the remainder value of seconds / 60. For example 61 % 60 = 1. This isn't the only way these values could be calculated.
To build the display string. I just put all of the hours, minutes and seconds in an array. Then used the map method, which applies the function makeTwoNumbers to all of the values. I then used the join method to join all the strings using the delimiter :. It just saves some typing and means you only reference makeTwoNumbers once, making it less work to use a different function later if you want to.
Hope that helps.
I realized that you could simply reset seconds, hours, and minutes to 0 and use a variable true. This would reset it entirely to 0. I couldnt believe how simple it was

Java Script Count Down Timer resets whenever page refreshes

I have PHP page, where I added a countdown for 30 min. and as it ticks when I refresh the page or perform a query of 'insert' and redirect back to that page, the timer gets reset.
I want the timer to be constant and continue count without any interruptions when the page gets refreshed.
My code goes as:
function startTimer(duration, display) {
var timer = duration,
minutes, seconds;
setInterval(function() {
minutes = parseInt(timer / 60, 10)
seconds = parseInt(timer % 60, 10);
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
display.textContent = minutes + ":" + seconds;
if (--timer < 0) {
timer = duration;
}
}, 1000);
}
window.onload = function() {
var fiveMinutes = 60 * 30,
display = document.querySelector('#time');
startTimer(fiveMinutes, display);
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="timer">
<div>Section</div>
<div class="time">
<strong>Time left: <span id="time">30:00</span></strong>
</div>
</div>
Any Help Is Appreciated..
Use html5 local storage to update the timer value and when page load occurs read the timer value from local storage. I guess no other way.
Whenever your PHP page loads, the javascript is loaded with it. So
window.onload = function () {
var fiveMinutes = 60 * 30,
display = document.querySelector('#time');
startTimer(fiveMinutes, display);
};
is called and the timer starts at 5 minutes.
One solution would be to do an Ajax request in window.onload and get the remaining time.
Another solution would be to set the fiveMinutes variable (obviously it should be renamed more appropriately) via PHP, if the javascript code is inside your PHP file, like
<script>
...
var timeLeft = <?php echo $timeLeft ?>;
...
</script>
The first solution is the standard way to go and the second one is the easy way to go.
As others have pointed out, you could use local storage (if the your target clients support this feature see here)
<script>
function startTimer(duration, display) {
var timer = duration, minutes, seconds;
setInterval(function () {
minutes = parseInt(timer / 60, 10)
seconds = parseInt(timer % 60, 10);
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
display.textContent = minutes + ":" + seconds;
timer = --timer;
if (timer >= 0) {
localStorage.setItem('time', timer);
//timer = duration;
}
}, 1000);
}
window.onload = function () {
var countDown = 60 * 30;
var oldVal = localStorage.getItem('time');
if (oldVal && oldVal > 0) {
countDown = oldVal;
}
var display = document.querySelector('#time');
startTimer(countDown, display);
};
</script>
edit: of course one must not forget to check whether the stored value is below zero.
As already pointed out, you could store the current time with localStorage.
To do so you would save both minutes and seconds in each interval tick:
function startTimer(duration, display) {
var timer = duration, minutes, seconds;
setInterval(function () {
minutes = parseInt(timer / 60, 10)
seconds = parseInt(timer % 60, 10);
localStorage.setItem("minutes", minutes); // <--
localStorage.setItem("seconds", seconds); // <--
And in the load function you'd read from them and set the starting value appropriately. It's important to note that values are always stored as strings, and as such, it would be necessary to parse them back to numbers before passing them through:
window.onload = function () {
var timeLeft = 60 * 30,
display = document.querySelector('#time');
var minutes = localStorage.getItem("minutes"); //read minutes
var seconds = localStorage.getItem("seconds"); //read seconds
if (minutes && seconds){
timeLeft = Number(minutes) * 60 + Number(seconds); //set time with val from storage
}
startTimer(timeLeft, display);
};
I changed the name of your fiveMinutes to timeLeft to better reflect what it holds, and parsed both values to numbers with Number().
It's also important to mention that while this does keep the value after refreshes, it doesn't "count" the time while the page was closed. So keep that in mind.
Instead of refreshing the whole page try to use Ajax for communication and modify your html page using javascript.

javascript countdown echoing wrong time

i want this my javascript code to to be able to be reading 3 hours countdown and also redirect to a new page after the countdown is complete
<script type="text/javascript">
// properties
var count = 0;
var counter = null;
window.onload = function() {
initCounter();
};
function initCounter() {
// get count from localStorage, or set to initial value of 1000
count = getLocalStorage('count') || 1000;
counter = setInterval(timer, 1000); //1000 will run it every 1 second
}
function setLocalStorage(key, val) {
if (window.localStorage) {
window.localStorage.setItem(key, val);
}
return val;
}
function getLocalStorage(key) {
return window.localStorage ? window.localStorage.getItem(key) : '';
}
function timer() {
count = setLocalStorage('count', count - 1);
if (count == -1) {
clearInterval(counter);
return;
}
var seconds = count % 60;
var minutes = Math.floor(count / 60);
var hours = Math.floor(minutes / 60);
minutes %= 60;
hours %= 60;
document.getElementById("timer").innerHTML = hours + "hours " + minutes + "minutes and " + seconds + " seconds left to complete this transaction"; // watch for spelling
}
</script>
<div id="timer"></div>
please help me make it better by making it been able to countdown to three hour and also redirect to another page after the countdown is complete
You didn't properly set total time. You set it to 16 minutes instead of 3 hours. Here is the working code (try it on JSFiddle):
var time = 60 * 60 * 3;
var div = document.getElementById("timer");
var t = Date.now();
var loop = function(){
var dt = (Date.now() - t) * 1e-3;
if(dt > time){
doWhateverHere();
}else{
dt = time - dt;
div.innerHTML = `Hours: ${dt / 3600 | 0}, Minutes: ${dt / 60 % 60 | 0}, Seconds: ${dt % 60 | 0}`;
}
requestAnimationFrame(loop);
};
loop();
Also, do not use setInterval and setTimeout for precise timing. These functions are volatile. Use Date.now() instead.

Categories

Resources