Timer control in javascript - javascript

I am using timer in my project , I am having two problems in it. When start button is press time should start & when end button is press time should end.
But 1)when end button is clicked
time is not stopping .
2)when time decrease & reach 1 minute..time is stopped ..it should reduse in seconds also
var tim;
var min = 10;
var sec = 10;
var f = new Date();
function f1() {
f2();
document.getElementById("starttime").innerHTML = "Your started your Exam at " + f.getHours() + ":" + f.getMinutes();
}
function f2() {
if (parseInt(sec) > 0) {
sec = parseInt(sec) - 1;
document.getElementById("showtime").innerHTML = "Your Left Time is :" + min + " Minutes ," + sec + " Seconds";
tim = setTimeout("f2()", 1000);
} else {
if (parseInt(sec) == 0) {
min = parseInt(min) - 1;
if (parseInt(min) == 0) {
clearTimeout(tim);
location.href = ".././Home/Login";
} else {
sec = 60;
document.getElementById("showtime").innerHTML = "Your Left Time is :" + min + " Minutes ," + sec + " Seconds";
tim = setTimeout("f2()", 1000);
}
}
}
}

My suggestion would be this:
Fiddle
var tim;
var sec;
var f = new Date();
function f1() {
sec = 10 * 60;
f2();
document.getElementById("starttime").innerHTML = "Your started your Exam at " + f.getHours() + ":" + f.getMinutes();
}
function f2() {
if (sec > 0) {
sec--;
tim = setTimeout(f2, 1000);
} else {
document.getElementById("starttime").innerHTML = "times up!!!!";
}
var min = Math.floor(sec / 60);
var secDisplay = sec % 60;
document.getElementById("showtime").innerHTML = "Your Left Time is : " + min + " Minutes," + secDisplay + " Seconds";
}
function end() {
clearTimeout(tim);
sec = 0;
f2();
}
Changes are:
Removed the min variable and only use the total seconds instead of two variables. We can easily calculate the minutes based on the total seconds, for the display purposes. Using the seconds variable makes it much easier to check the time remaining. As you can see the code is simplified a lot.
Changed the setTimeout to take the function as an argument, not a string.
Added end() function, to be called when the end button is clicked.
Moved the seconds count to inside f1() so that it can be started and ended repeatedly without reloading the page.
Removed unnecessary parseInt() calls. The sec variable is already of numerical type so no need to convert it.
The timer will stop when the seconds reduce to 0. If you want it to stop when the time remaining reaches one minute, just change the condition in f2() to if (sec > 60) {

For your first question about the end button i cannot see any end button functionality. but you could have a stop function that clears the timeout.
function f3() {
clearTimeout(tim);
//update any text you wish here or move to the next page..
}
For your second question why it ends at 1 minute. You are decreasing the minute value before you check if it is zero. So when you come to f2, sec is 0 and min is 1 you then decrease min to 0.. And then check if it is zero and end the execution.
To solve that move your "min = parseInt(min) - 1;" to after the else and it should count the last minute too.
PS. you don't need parseint since you are using numbers allready

Related

Countdown based on timezone with jQuery

I worked with this:
(function() {
var timeElement, eventTime, currentTime, duration, interval, intervalId;
interval = 1000; // 1 second
// get time element
timeElement = document.querySelector("#countdown");
// calculate difference between two times
eventTime = moment.tz("2022-05-29T08:00:00", "Europe/Berlin");
// based on time set in user's computer time / OS
currentTime = moment.tz();
// get duration between two times
duration = moment.duration(eventTime.diff(currentTime));
// loop to countdown every 1 second
setInterval(function() {
// get updated duration
duration = moment.duration(duration - interval, 'milliseconds');
// if duration is >= 0
if (duration.asSeconds() <= 0) {
clearInterval(intervalId);
// hide the countdown element
timeElement.classList.add("hidden");
} else {
// otherwise, show the updated countdown
timeElement.innerText = duration.days() + ":" + duration.hours() + ":" + duration.minutes() + ":" + duration.seconds();
}
}, interval);
}());
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.1/moment-with-locales.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.17/moment-timezone-with-data-2012-2022.min.js"></script>
<div id="countdown"></div>
Unfortunately, the time doesn't get calculated correctly. If you change for example 2022-05-29 to 2022-08-29, nothing changes. Additionally, every value should have two digits.
Has someone an idea to fix that? Would be very thankful!
Your question about momentjs is answered here; use asDays() not days()
You can pad a string with 0's using the function padStart(length, withWhat) Mozilla Developer Network Documentation
//...snip...
} else {
// otherwise, show the updated countdown
timeElement.innerText =
duration.asDays().toFixed().padStart(2, 0) + ":" +
duration.hours().toString().padStart(2, 0) + ":" +
duration.minutes().toString().padStart(2, 0) + ":" +
duration.seconds().toString().padStart(2, 0);
}
//...snip...

Repeat timer infinite amount of times

I am trying to add a countdown timer to my Shopify checkout using Google Optimize. I got this to work using the following HMTL & JS. Taken from here
However once the timer finishes and I reload the page it starts from 17 seconds instead of 5 minutes.
Is there a way to get this to repeat the timer from 5 minutes once it hits 0?
document.getElementById('timer').innerHTML =
05 + ":" + 00;
startTimer();
function startTimer() {
var presentTime = document.getElementById('timer').innerHTML;
var timeArray = presentTime.split(/[:]+/);
var m = timeArray[0];
var s = checkSecond((timeArray[1] - 1));
if(s==59){m=m-1}
if(m<0){
return
}
document.getElementById('timer').innerHTML =
m + ":" + s;
console.log(m)
setTimeout(startTimer, 1000);
}
function checkSecond(sec) {
if (sec < 10 && sec >= 0) {sec = "0" + sec}; // add zero in front of numbers < 10
if (sec < 0) {sec = "59"};
return sec;
}
<div>Your cart is reserved for <span id="timer"></span></div>
If you could give the answer like you are talking to a complete beginner it would be greatly appreciated.
Looks like I have a lot to learn!
Welcome to StackOverflow. This should help out...
//JAVASCRIPT
startTimer(5); // SPECIFY AMOUNT OF MINUTES OR NO PARAMETER FOR DEFAULT 5
function startTimer(minutes = 5){
var timeout = minutes * 60000;
var ms = timeout;
var interval = setInterval(function(){
ms -= 1000;
if(ms >= 0) {
var d = new Date(1000*Math.round(ms/1000));
document.getElementById('timer').innerHTML = getMS(d);
} else {
startTimer(5); // MAKE TIMER RESTART AGAIN FOR 5 MINS
// clearInterval(interval); // TO MAKE TIMER STOP UPON REACHING 0:00
}
}, 1000);
}
function getMS(d){
return pad(d.getUTCMinutes()) + ':' + pad(d.getUTCSeconds());
}
function pad(i) {
return ('0'+i).slice(-2);
}
<!--HTML -->
<body>
<div>Your cart is reserved for <span id="timer"></span></div>
</body>
In javascript the setInterval function allow you to make anything you want every fixed ms.
interval = setInterval(() => {
console.log('Waited for 5m');
// Do whatever you want
console.log('Waiting for 5m again...');
}, 300000);
// To stop the interval
clearInterval(interval);

Multi countdown

I have a web page where I entered a countdown code and it works well. However, I can only call it 1 time with the id in html.
Second or third time, it no longer works. How can I always use it? I would need it 3 or 4 times on the page. Thank you.
This is the code:
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 + " ore " + minutes + " min " + seconds + " sec"; // watch for spelling
}
You need to encapsulate the functionality in a way that can be called many times. It usually helps to think about the question "As a programmer, how I'd like to use this?"
Usually, it's a single function that takes some parameters and does something and/or returns something.
As an example... wouldn't it be nice if we had a function startMyTimer(...) that takes a timerId, and an element and sets up a timer that will update that element? We already have the signature:
function startMyTimer(timerId, element) { ... }
And now you can build everything inside this function. JS allows declaring functions within functions, which helps with encapsulation, so copying from your code it would look like:
function startMyTimer(timerId, element) {
var count = getLocalStorage(timerId) || 1000;
var counter = setInterval(timer, 1000); //1000 will run it every 1 second
function timer() {
count = setLocalStorage(timerId, 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;
element.innerHTML = hours + " ore " + minutes + " min " + seconds + " sec"; // watch for spelling
}
}
Note that now count and counter are both private to the scope of startMyTimer, so only within this function (and any function inside this one, such as function timer()) will see these variables.
So if you want to do exactly what you did, you'd use this function as
window.onload = function() {
startMyTimer('count', document.getElementById("timer"));
};
Again, this is just an example of a posible solution - Maybe you could pass in the element id instead of the element, or a timer duration, etc., and the best solution is the one that fits best your needs.

Reset Timer every x minutes/hour

I am trying two create to separate timers. One timer counts down to a date and displays a countdown and the other counts down on an interval and resets (ie: 5 hours and resets).
The one I am having trouble with is the second option. I am trying to create a countdown that is relative to real-time and then resets once it reaches zero. So for example setting it to 2 days and 5 hours. Once this completes the clock resets to 2 days 5 hours. I am having trouble getting the clock to reset at the specified time and loop without having negative numbers. I tried this two separate ways but feel like I am over-complicating things.
The reason I use real-time is so that the clock will be the same if you open it in another tab. If I create a regular timer it will reset upon refreshing the page.
codpen
In this example I tried to reset the counter every 40 seconds but couldn't get it to work. Ultimately I want to be able to specify the date with ie: 00:12:00 (12 hours countdown) and then have it reset automatically. I just can't figure out how to maintain the counting without going to negative numbers or freezing it.
function timer() {
var currentTime = new Date()
var date = currentTime.getDate()
var hours = currentTime.getHours()
var minutes = currentTime.getMinutes()
var seconds = currentTime.getSeconds()
var daysLeft = 0;
var hoursLeft = 24 - hours;
var minsLeft = 60 - minutes;
var secsLeft = 60 - seconds;
// counter freezes at 40 seconds and hangs for 20seconds
if(secsLeft => 40) {
secsLeft = 40 - seconds
if(secsLeft < 0) {
secsLeft = 40
}
}
document.getElementById('timerUpFront').innerHTML= "<br><br><strong>Duration Countdown with Infinite Reset #2</strong><br>" + daysLeft + " days " + hoursLeft + " hours " + minsLeft + " minutes " + secsLeft + " seconds";
}
var countdownTimer = setInterval('timer()', 1000);
codpen
you can separate the timer to functions to simplify it and apply the following logic
function startTimer () {
val targetRemainedSeconds = // calculate the value
val remainedSeconds = targetRemainedSeconds
setInterval(timer(), 1000)
}
function timer () {
remainedSeconds--
if (remainedSeconds < 0) reaminedSeconds = targetReaminedSeconds // reset the timer
timerUpdate()
}
function timerUpdate() {
// use 'remainedSeconds' to update timer
}

clearInterval is not clearing setInterval

I have made a memory game with a timer that start at 10 minutes and counts down every second to 0. This function is only called once and has the following setInterval function:
game.countdown = setInterval(function() {
if(game.timeLeft <= 0){
gameEnded = true;
}
if(!gameEnded){
// lower one second
game.timeLeft--;
var timespan = document.querySelector('.timeleft');
var minutes = pad(Math.floor((game.timeLeft / 60)),2 );
var newSeconds = pad(Math.floor(game.timeLeft - (minutes * 60)),2 );
function pad(num, size) {
var s = num+"";
while (s.length < size) s = "0" + s;
return s;
}
var niceTime = minutes + ":" + newSeconds;
timespan.innerHTML = niceTime;
// Then alter time bar on .innertimer
// Calculate percentage starting at 0%
var percentageDone = (Math.floor((10*60 - game.timeLeft) / (10*60) * 10000) / 100);
$(".timer").css({"background": "-webkit-linear-gradient(left, white " + percentageDone + "%, green " + percentageDone + "%)"});
}
}, 1000);
I store the setInterval in object game under variable name countdown. When the game is ended I call another function that has the clearInterval:
clearInterval(game.countdown);
Then when it goes to the next level it calls the setInterval function again and stores it again in game.countdown. But now for every second it takes 2 seconds. The next level 3 seconds. You can see there are multiple setInterval's at work because it's not done at the same time.
Hope someone can really help me out debugging this problem.
What I've done to work around the issue is the following. The interval is only being called if the following is true:
if (undefined == game.countdown){
This way if there is a countdown defined it's calling it again. And since I'm storing the game.timeLeft not in the function itself I can just refill game.timeLeft.

Categories