I'm a complete noob to JS trying to use it for the first time for a school project.
My goal is to have a timer that counts down upon pressing a button. The countdownClock function is then called with the Unix time 10 minutes in the future as a parameter. My code seems to work decently well but upon pressing the button again, it creates a weird alternating glitch where both timers are functioning simultaneously.
What can I do to forget about the previous timer upon repressing the button? Thank you!
function countdownClock(time){
// Set the date we're counting down to
var countDownDate = (time + "000");
// Update the count down every 1 second
var x = setInterval(function() {
// Get today's date and time
var now = new Date().getTime();
// Find the distance between now and the count down date
var distance = countDownDate - now;
// Time calculations for days, hours, minutes and seconds
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
// Output the result in an element with id="demo"
document.getElementById("timer").innerHTML = minutes + "m " + seconds + "s ";
// If the count down is over, write some text
if (distance < 0) {
clearInterval(x);
document.getElementById("timer").innerHTML = "GAME OVER";
}
}, 1000);
}
I'm guessing you copied this from somewhere, since it already has what you need - clearInterval would give you the result you are looking for, and you should only need minimal changes
var intervalId;
function countdownClock(time){
// Set the date we're counting down to
var countDownDate = (time + "000");
// clear the old one, if relevant
if (intervalId)
clearInterval(intervalId)
intervalId = setInterval(function() {
// Get today's date and time
var now = new Date().getTime();
// Find the distance between now and the count down date
var distance = countDownDate - now;
// Time calculations for days, hours, minutes and seconds
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
// Output the result in an element with id="demo"
document.getElementById("timer").innerHTML = minutes + "m " + seconds + "s ";
// If the count down is over, write some text
if (distance < 0) {
clearInterval(intervalId);
document.getElementById("timer").innerHTML = "GAME OVER";
}
}, 1000);
}
Related
This question already has answers here:
How to write a countdown timer in JavaScript? [closed]
(3 answers)
Closed 7 months ago.
I'm currently working on a flight entertainment system project that contains a timer that specifies how long is left in the flight.
I want to write a function that specifies a certain time such as "3 hours 20mins" and countdown from that.
I need it to run from when I open the page and reset it automatically whenever it hits 0. Its really just there for aesthetics. It can be seen in the top right of the image I attached.
Right now I just have regular text in my HTML file :
<div class="flighttime">
3H 20M
</div>
function addTime(hours, minutes, date = new Date()) {
date.setTime(date.getTime() + hours * 3600000 + minutes * 60000);
return date.getTime();
}
const time = document.getElementById('time');
const [hours, minutes] = time.textContent.split(' ').map(i => parseFloat(i));
console.log(hours, minutes)
var countDownDate = addTime(hours, minutes)
// Update the count down every 1 second
var x = setInterval(function() {
// Get today's date and time
var now = new Date().getTime();
// Find the distance between now and the count down date
var distance = countDownDate - now;
// Time calculations for days, hours, minutes and seconds
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
// Display the result in the element with id="demo"
time.innerHTML = hours + "H "
+ minutes + "M " + seconds + "S";
// If the count down is finished, write some text
if (distance < 0) {
clearInterval(x);
time.innerHTML = "EXPIRED";
}
}, 1000);
<div id="time">3H 30M</div>
I'm trying to display a countdown in several div tags with the same class.
But the problem is that only the last tag of the list contains the countdown.
Here is code:
const contentsDownDate = document.querySelectorAll(".countDown");
nbElement = contentsDownDate.length - 1;
for (var i = 0; i < nbElement; i++) {
var countDownDate = new Date("Jan 5, 2024 15:37:25").getTime();
// Update the count down every 1 second
x = setInterval(function() {
// Get today's date and time
var now = new Date().getTime();
// Find the distance between now and the count down date
var distance = countDownDate - now;
// Time calculations for days, hours, minutes and seconds
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
// Output the result in an element with id="demo"
contentsDownDate[i].innerHTML = days + "d " + hours + "h " +
minutes + "m " + seconds + "s ";
// If the count down is over, write some text
if (distance < 0) {
clearInterval(x);
contentsDownDate[i].innerHTML = "EXPIRED";
}
}, 1000);
}
I did the same thing by calling ids but still the same result, only the last id displays the countdown.
What can I do to solve this problem?
Note that the countdown code is taken from this: w3schools
PS: I also read that innerHTML prints at the end of the loop so it only prints the last tag and so you have to stop/pause the loop to print, especially with setInterval, but I already did it.
Unless this one was to update the countdown time? But in that case where should I place the other setInterval?
The reason why this is not working is because you enter the infinite loop in a blocking state, meaning that the interval is never entered as the browser is busy looping. Imagine the browser can only do one thing at a time, as in a single thread, so the loop is it, and cannot do anything else until it's done, and in your case it never.
Basically, if you put a setInterval() inside loop without clear it then the setInterval never stop and that mean the loop is infinite so it never complete.
Instead of that, put the loop inside the setInterval() will do the job. Let try this:
const contentsDownDate = document.querySelectorAll(".countDown");
nbElement = contentsDownDate.length-1;
var countDownDate = new Date("Jan 5, 2024 15:37:25").getTime();
// Update the count down every 1 second
x = setInterval(function() {
for (i=0; i<=nbElement; i++){
// Get today's date and time
var now = new Date().getTime();
// Find the distance between now and the count down date
var distance = countDownDate - now;
// Time calculations for days, hours, minutes and seconds
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
// Output the result in an element with id="demo"
contentsDownDate[i].innerHTML = days + "d " + hours + "h "
+ minutes + "m " + seconds + "s ";
// If the count down is over, write some text
if (distance < 0) {
clearInterval(x);
contentsDownDate[i].innerHTML = "EXPIRED";
}
}
}, 1000);
I’ve seen several examples for Javascript/jQuery countdown timers. I have implemented a 15 minute countdown timer based off the example at w3schools. However, I would like to add an update feature that allows me to add/subtract time to and from the clock. The timer starts at 15 minutes.
In my project the user will answers questions. After they answer the question and select submit, a time penalty or bonus is given. The penalty subtracts 3 seconds from the clock. The bonus adds 2 seconds to it. Below is an example of my code:
var mission_timer = 15;
function start_timer(){
countDownDate = new Date().getTime() + mission_timer * 60 * 1000;
timer_interval = setInterval(function() {
var now = new Date().getTime();
var distance = countDownDate - now;
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var minutes_number_length = Number(String(minutes).length);
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
var seconds_number_length = Number(String(seconds).length);
current_time = document.getElementById("game_timer").innerHTML = "TIME: " + minutes + ":" + seconds;
update_timer = null;
time_update = 0;
if (current_time === "TIME: 00:00") {
$("#game_timer").css("color", "red");
clearInterval(timer_interval);
console.log("Time Expired");
}else
if (current_time === "TIME: 01:00") {
$("#game_timer").css("color", "yellow");
console.log("One Minute Left");
}
}, 1000);
}
The counter works using countDownDate and now. You have to modify the countDownDate variable to add/substract time when user answers the questions.
//bonus for correct answer
countDownDate += 2 * 1000;
And
//penalty for wrong answer
countDownDate -= 3 * 1000;
Both of them have to be triggered by the Submit event of the question answered.
Here are my code on my current program. I have a running code for countdown timer my problem now is when the VOTING PERIOD ENDS I want to display Voting Ends instead of it always displaying voting open.
<script>
// Set the date we're counting down to
var countDownDate = new Date("<?php echo $countdown['datestart']; ?>").getTime();
var endDate = new date("<?php echo $countdown['dateend']; ?>").getTime();
// Update the count down every 1 second
var x = setInterval(function() {
// Get todays date and time
var now = new Date().getTime();
// Find the distance between now an the count down date
var distance = countDownDate - now;
// Time calculations for days, hours, minutes and seconds
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
// Output the result in an element with id="demo"
document.getElementById("demo").innerHTML = days + "d " + hours + "h "
+ minutes + "m " + seconds + "s ";
// If the count down is over, write some text
if (distance < 0) {
clearInterval(x);
document.getElementById("demo").innerHTML = "Voting now Opens";
}
// If date end is over display some text
//display voting period ends
}, 1000);
</script>
At a glance, i can see that your "endDate" line has an error:
var endDate = new date(.....
it should be Date with a capital 'D' as is for the var countDownDate i.e.
var endDate = new Date(.....
Assuming the rest of the code is correct (and it seems ok) - should be fine.
If that doesn't solve it - from your question it is easy to decipher that the if the following function always resolves to false and hence will never fire enclosed code which clears the 'x' interval and shows that voting is open.
if (distance < 0) {...}
If what I would do is console.log(countDownDate);, console.log(now); and why not also console.log(distance); ideally immidiately after the declaration:
// Find the distance between now an the count down date
var distance = countDownDate - now;
if you are unsure how to use the console.log() function please refer to the following link: https://developers.google.com/web/tools/chrome-devtools/console/
To add the end voting message, you will need to continue the interval until the voting has ended. To make things a little simpler, we have split the code into 3 sections using if...else if...else. In each of these, we handle the respective display for that scenario. It has the added benefit of not doing calculations when it is not needed.
If distance > 0, the voting has not started.
If endDate > now, the voting hasn't ended. I am assuming that the PHP output will result in an accurate date for this scenario. Read more.
Any other scenario means voting has ended.
<script>
// Set the date we're counting down to
var countDownDate = new Date("<?php echo $countdown['datestart']; ?>").getTime();
var endDate = new Date("<?php echo $countdown['dateend']; ?>").getTime();
// Update the count down every 1 second
var x = setInterval(function() {
// Get todays date and time
var now = new Date().getTime();
// Find the distance between now an the count down date
var distance = countDownDate - now;
if (distance > 0) {
// Time calculations for days, hours, minutes and seconds
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
// Output the result in an element with id="demo"
document.getElementById("demo").innerHTML = days + "d " + hours + "h "
+ minutes + "m " + seconds + "s ";
}
else if (endDate > now) {
// If the count down is over, write some text
document.getElementById("demo").innerHTML = "Voting now Opens";
}
else {
// If date end is over display some text
//display voting period ends
document.getElementById("demo").innerHTML = "Voting Ended";
clearInterval(x);
}
}, 1000);
</script>
I have a program which I wrote with html just like a website but runs offline so I want to add 35 minutes countdown after the user have logged in then when the 35 minutes is exusted the user will be logged out
But I can't get the code right because I am new to javascript but I was able to get it to count for 60seconds and after that it will alert the user with "logout" but I want it to log the user out not to alert the user to logout
This is the html code
<div id="counter">1:00</div>
And this is the javascript code
function countdown() {
var seconds = 60;
function tick() {
var counter = document.getElementById("counter");
seconds--;
counter.innerHTML = "0:" + (seconds < 10 ? "0" : "") + String(seconds);
if( seconds > 0 ) {
setTimeout(tick, 1000);
} else {
alert("Game over");
}
}
tick();
}
countdown();
<script>
// Set the date we're counting down to
var countDownDate = new Date("July 12, 2017 09:00:00").getTime();
// Update the count down every 1 second
var x = setInterval(function() {
// Get todays date and time
var now = new Date().getTime();
// Find the distance between now an the count down date
var distance = countDownDate - now;
// Time calculations for days, hours, minutes and seconds
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
// Output the result in an element with id="counter"
document.getElementById("counter").innerHTML = days + "d " + hours + "h "
+ minutes + "m " + seconds + "s ";
// If the count down is over, write some text
if (distance < 0) {
clearInterval(x);
document.getElementById("counter").innerHTML = "EXPIRED";
}
}, 1000); // time changes in every 1 second
</script>
<p2>to go</p2>
try this out, change date and time according to your need
Handling sessions in the frontend is not the best way to approach this, but since you asked...
Your method seems correct, I mean you just have to change 60 seconds with 2100 (for 35 minutes) seconds. To logout you'd need a function or a page to log them out.
The problem with this method is that if they refresh the page the counter also refreshes, also they can directly change the javascript if they want, rewrite the function and so many other things...
Luckily for you Javascript now supports something called session storage and local storage, so you can store your timer in one of these variables and even if they refresh the page you don't lose their latest value. Session variables last for as long as the browser is open, local variables last until forever, or if until you unset them.
You can set storage values like this:
var latestTime = localStorage.getItem('secondsPassed');
localStorage.setItem('secondsPassed', lastTime+1);
This will at least get around them refreshing the page and closing-reopening the browser to refresh the timer!
If you want to learn how to handle sessions properly read into PHP since the backend is the best way to handle these kind of things.
function countdown() {
var timeoutMinutes = 35;
var startTime = new Date();
var elapsedSecond = 0;
function tick() {
var counter = document.getElementById("counter");
var currentTime = new Date();
elapsedSecond = (currentTime - startTime) / 1000;
counter.innerHTML = formatPlaces("0") + ":"
+ formatPlaces(elapsedSecond / 60) + ":"
+ formatPlaces(elapsedSecond % 60);
if (elapsedSecond <= timeoutMinutes * 60) {
setTimeout(tick, 1000);
} else {
alert("Game over");
}
}
tick();
}
function formatPlaces(value) {
var intValue = parseInt(value);
return intValue.toString().length == 1 ? "0" + intValue.toString() : intValue.toString();
}
countdown();
<div id="counter">00:00</div>