I have a page that runs reloadData() function every 5 seconds:
setTimeout('reloadData()', 5000);
I have an element that I'd like to update with a countdown from 5 to 0 for every second of the reloadData();
document.getElementById('countdown').value
What is the proper way to do achieve this effect?
Example:
reloadData() {} starts
Element "countdown" will show: 5... 4... 3...
2... 1... (at second intervals)
reloadData(){} starts again
I'm not completely sure how to interpreter your question, but I guess you have a function reloadData which should run every 5 second.
You will now have a counter showed which will found from 5..1 for each second.
When then counter reaches 0 you want to repeat, eg calling reloadData() and count again?
var counter = 0;
setInterval(function() {
if (counter == 0) {
reloadData();
}
// do stuff with i which will be 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
// ...
document.getElementById('countdown').value = 5 - counter;
// ...
counter++;
counter %= 5;
}, 1000);
More like 6 seconds because I hang out on reload for a bit, but you can use requestAnimationFrame to call your function (about 60 times a second) and check the date to see if you're over a second. Then update your counter.
As in this example:
https://jsfiddle.net/subterrane/k2aacj4s/
Output div:
<div class="container" id="counter"></div>
Some script:
var counter = document.querySelector("#counter");
var count = 5;
var start = Date.now();
function work() {
if (count == 0) {
counter.innerText = "reload!";
} else {
counter.innerText = count;
}
var now = Date.now();
if (now >= start + 1000) {
start = now;
count--;
if(count < 0) count = 5;
}
window.requestAnimationFrame(work);
};
work();
Related
I need to make a countdown happen from 10 to 0 using a loop. The loop should replace the need to repeat the code 10X. I also neeed to display the countdown to the user in the HTML. Help!
<script>
function StartTheCountdown()
{
var Countdown = 10;
// Used to keep track of actual time.
// 1000 = 1 second because we are using milliseconds.
var timeout = 10000;
setTimeout(() => {
document.getElementById("CountDownDisplay").innerHTML = "Blastoff!";
Countdown = Countdown - 1;
}, timeout)
timeout = timeout - 1000;
// We need to do this 10 times **************************************
setTimeout(() => {
document.getElementById("CountDownDisplay").innerHTML = Countdown;
Countdown = Countdown - 1;
}, timeout)
timeout = timeout - 1000;
}
</script>
Use setTimeout to repeatedly call the function until count is zero, and then display a message.
// Cache your element
const div = document.querySelector('div');
// Initialise your count to 10
function countdown(count = 10) {
// Update your element textContent
div.textContent = `T-minus: ${count}`;
// Call the function again if the count
// is greater than 0 with a decremented count
if (count > 0) {
setTimeout(countdown, 1000, --count);
// Otherwise update the textContent of the
// element with a message
} else {
div.textContent = 'Blast off!';
}
}
countdown();
<div></div>
Additional documentation
Template/string literals
i would like to add another counter in this code:
function animateValue(id) {
var obj = document.getElementById(id);
var counter = getLocalStoregaValue();
var current = counter ? +counter : obj.innerHTML;
obj.innerHTML = counter;
setInterval(function() {
var counter = current--;
obj.innerHTML = counter;
localStorage.setItem('counter', counter);
}, 1000);
}
function getLocalStoregaValue() {
return localStorage.getItem('counter');
}
animateValue('value');
I would like it to scale once every second (as in this case) and once every 5 seconds. How can I? And then, how can I make it stop at 0? So without negative numbers. Thank you very much.
EDIT: I explained myself wrong.
I would like a single counter that drops in number from a minimum of 10 to a maximum of 20.
Example: the counter marks 50. After 15 seconds it marks 49. After 18 seconds it marks 48. After 11 seconds it marks 47. And so up to 0.
I hope I explained myself well this time :)
Ok, I was interrupted while posting my answer. Here now the explanation:
I left out the localStorage part of your question and concentrated on the generation of "independent countdowns" first:
function cntdwn(sel,stp,intv){
let el=document.querySelector(sel),
n=el.textContent-stp,
cd=setInterval(()=>{
el.textContent=n;
if((n-=stp)<0) clearInterval(cd);
}, intv);
}
cntdwn('#one',1,1000) ;
setTimeout(()=>cntdwn('#two',1,3000), 12000);
<p>first countdown:<br>step: 1, interval: 1s</p>
<p id="one">15</p>
<p>second countdown:<br>step: 1, action after: 15, 18, 21, 24 ... s (as mentioned in comment)</p>
<p id="two">50</p>
The cntdwn() function provides a scope in which individual countdowns can be set up for arbitrary DOM elements, each with their own counter (it starts with the value found in the DOM element), step-width and interval (in milliseconds).
Each countdown is generated with let cd=setInterval(...). The reference cd can then be used to stop the countdown (in clearInterval(cd)), once the value of n is found to be below zero.
Edit:
Assuming you made a typo in your sequence of intervals and you really meant: 15, 18, 21 seconds, then the edited second countdown should be the correct solution.
I used a setTimeout() function to delay the action by 12 seconds, then, after the first of the regular 3 second intervals (i. e. after a total of 15 seconds) the first change occurs. The countdown then continues in 3 second intervals until it reaches zero.
Yet another edit:
Ok, so you want: "A countdown with random time intervals (range 10 to 20s each) that will stop at zero"
This should do it:
function cntdwn(sel,int1,int2){
let el=document.querySelector(sel),
n=el.textContent-1,
cd=()=>setTimeout(()=>{
el.textContent=n;
if(n--) cd();
}, 1000*(int1+Math.random()*(int2-int1)));
cd();
}
cntdwn('#one',10,20);
<p>countdown:<br>step: 1, intervals: between 10 and 20 s</p>
<p id="one">5</p>
If you can use ES2017, you can use an asynchronous function to do it, like this:
async function animateValue(id) {
function timeout(t){
return new Promise(r => setTimeout(r, t))
}
var obj = document.getElementById(id);
var counter = getLocalStoregaValue();
for(let i = +counter || +obj.innerHTML || 0; i >= 0; i--){
obj.innerHTML = i;
localStorage.setItem('counter', i);
await timeout((Math.random() * 10 + 10) * 1000); //Pause for 10 to 20 seconds. For an integer second value, wrap `Math.random() * 10` into a `Math.floor` call
};
}
function getLocalStoregaValue() {
return localStorage.getItem('counter');
}
animateValue('value').catch(console.error);
<div id="value">50</div>
Try it (I commented out the localStorage part, as it isn't allowed in Stack Snippets):
async function animateValue(id) {
function timeout(t){
return new Promise(r => setTimeout(r, t))
}
var obj = document.getElementById(id);
var counter = getLocalStoregaValue();
for(let i = +counter || +obj.innerHTML || 0; i >= 0; i--){
obj.innerHTML = i;
//localStorage.setItem('counter', i);
await timeout((Math.random() * 10 + 10) * 1000); //Pause for 10 to 20 seconds. For an integer second value, wrap `Math.random() * 10` into a `Math.floor` call
};
}
function getLocalStoregaValue() {
//return localStorage.getItem('counter');
}
animateValue('value').catch(console.error);
<div id="value">50</div>
I'm trying to use the system clock to make a simple animation in Javascript. I want to cycle through an array so that [0],[1],[2]... are called at 500ms intervals. Using an example from a previous Stack Overflow answer I was experimenting with this code snippet:
function timer(time,update,complete) {
var start = new Date().getTime();
var interval = setInterval(function() {
var now = (time*1000)-(new Date().getTime()-start);
if( now <= 0) {
clearInterval(interval);
complete();
}
else update(Math.floor(now/1000));
},500); // the smaller this number, the more accurate the timer will be
}
The function is then called using the following approach:
timer(
5, // seconds
function(timeleft) { // called every step to update the visible countdown
console.log(3 - timeleft );
},
function() { // what to do after
console.log("Timer complete!");
}
);
This produces, 0,1,2,3,"Timer Complete". However, I can't figure out how this can be called at 500ms intervals. I've tried tweaking the numbers, but I realize that I don't fully understand how this function works. Is it possible to adjust this, or are there some hard coded browser functions that are being called here on the 1s interval?
I tried changing all of the values to the following:
function timer(time,update,complete) {
var start = new Date().getTime();
var interval = setInterval(function() {
var now = (time*500)-(new Date().getTime()-start);
if( now <= 0) {
clearInterval(interval);
complete();
}
else update(Math.floor(now/500));
},500); // the smaller this number, the more accurate the timer will be
}
timer(
5, // seconds
function(timeleft) { // called every step to update the visible countdown
console.log(5 - timeleft );
},
function() { // what to do after
console.log("Timer complete!");
}
);
This now produces:
2
3
4
5
Timer complete!
at what I think are 500ms intervals, but I'm not sure. Changing the value 5 in 5 - timeleft also does strange things to the speed at which this runs.
I believe you're overcomplicating this. If all you want is to display each item from an array every 500ms, use a regular counter, not timestamps and rounding:
function timer(myArray) {
var counter = 0;
var interval = setInterval(function() {
// There are still items we want to display
if(counter < myArray.length) {
console.log(myArray[counter]);
// We have displayed all
} else {
console.log('Finished');
clearInterval(interval);
}
// Increment counter
counter++;
}, 500); // 500 here is the interval in msec
}
var arr = ['Item 0', 'Item 1', 'Item 2', 'Item 3'];
timer(arr);
http://jsfiddle.net/AE58p/
I am working on a simple game right now. its almost done except for the timer has a glitch in it and I can't figure out whats doing it. when you push a button, an HTML5 text on the canvas starts to count down from 35 to 0. On the first run it's fine. But if you choose to play again with out refresh the timer starts to countdown faster. here is the code.
var timer = 35;
ctx.fillText("Countdown: " + timer, 320, 32);
function resetReggie(){
reggie.x = canvasWidth / 2;
reggie.y = canvasHeight / 2;
}
//Starts Timer for Timed Game
function timedMsg()
{
resetReggie();
ballsCaught = 0;
timer = 35;
alert('Pick up as many as you can in ' + timer + ' seconds');
countDown();
var t=setTimeout(function() {
var again = confirm("TIMES UP! You Gathered " + ballsCaught + " Balls! Play Again?");
if (again === true){
timedMsg();
resetReggie();
}
if (again === false){
resetReggie();
ballsCaught = 0;
timer = 35;
}
}, timer * 1000);
}
function countDown() {
if (timer != 0){
timer-=1;
setTimeout('countDown()', 1000);
}
}
I think the problem is in the line
}, timer * 1000);
where you have a value that is at most 34 at the time 'timer' is evaluated to set the timeout. Because you initialize it to 35 but then call countDown() which decreases it to 34, then you have a call to confirm() which might let 'timer' decrease even more. As a result the subsequent call to timedMsg() happens a little too soon causing countDown() to be called twice as often. Try the following (I ran it in node) and then change the 4 to 6.
function countDown() {
console.log("Countdown: " + timer, 320, 32);
if (timer != 0) {
timer -= 1;
setTimeout(countDown, 1000);
}
}
function timedMsg() {
timer = 5;
countDown();
var t=setTimeout(function() {
timedMsg();
}, 4 * 1000);
}
timedMsg();
As mentioned in my comment, each time you start a new game, it appears you are decreasing the timeout value. As a result, this reduces the time each time.
Try this:
var timeout = currentTime = 5;
var int = setInterval(function() {
console.log(currentTime);
currentTime--;
if(currentTime < 0) {
var again = confirm('Play again?');
if(again) {
currentTime = timeout;
}
else {
clearInterval(int);
}
}
}, 1000);
http://jsfiddle.net/gRoberts/CsyYx/
Look at your console (F12 in Chrome), or update the code to write to the browser to see it working ;)
I want to count down from 10 seconds to 0. When it have reached 0 the DIV will reload and the timer will start over again. I have this function that allows it to do exactly like I wanted but the problem is that when the countdown have reached 0 and going back to 10, it will count -1 reload -2 reload -3 reload -4 reload and so on. That is not how I want it! :)
Here's my code:
var time = setInterval(countdown, 1000);
function countdown() {
var count = 10;
countdown = setInterval(function() {
$('#countdown').html(count + ' sekunder kvar');
if(count == 0) {
$('#weather-data').load('jquery-fetch/fetch-weatherdata.php?place=' + myplace);
clearInterval(countdown);
}
count--;
}, 1000);
}
How can I fix my problem so the timer counts down from 10 to 0 and repeat that countdown forever?
Thanks in advance.
EDIT
When this function has reached 0 for the first time and starts over, it counts like this: 10, 9, 8, 10, 7, 6, 5, 4, 3, 2, 1, 10, 9, 8, 7, 10, 6, 5, 4, 3, 2, 1, 10, 9, 8, 10, 7, 6, and so on. Why does it act like this with this code?
function countdown() {
var count = 10;
var timerId = setInterval(function() {
$('#countdown').html(count + ' sekunder kvar');
count--;
if(count == 0) {
$('#weather-data').load('jquery-fetch/fetch-weatherdata.php?place=' + myplace);
clearInterval(timerId);
countdown();
}
}, 1000);
}
countdown();
Thanks in advance!
I see a lot of problems in your script... So not sure how you even get that to work..
Function name can't have -, so that call won't work :S
countdown is a global variable inside your function countdown() which is the same as your function name, effectively a countdownception
You are effectively creating a new Interval every one second as you are calling countdown
To achieve what you want, try the simpler:
function countdown() {
// your code goes here
var count = 10;
var timerId = setInterval(function() {
count--;
console.log(count);
if(count == 0) {
// your code goes here
count = 10;
}
}, 1000);
}
countdown();
http://jsfiddle.net/Xrbm5/13/
Take a look at what your code is doing.
You are setting an interval to run every second. That's fine.
What isn't fine is that, every second, that interval is creating a NEW interval that individually counts down from 10.
Also, you are setting countdown as a global variable. So when your first counter reaches zero, it actually clears the LAST timer, leaving the first one to happily continue into negative numbers, all the while you're spawning new intervals.
Overall, it's a disaster.
If you just want to update the page every 10 seconds, then:
setTimeout(function() {
// run some code
},10000);
If you want a count down, then reset just the counter at each even number of 10. The following adds start and stop functions, it re-stats from where it left off. Also, if running, clicking start doesn't start another one.
var weatherRefresh = (function() {
var count = 10;
var timerRef;
return {
start: function() {
// If already running, leave it running
if (timerRef) return;
timerRef = setInterval(function() {
// Display count
document.getElementById('dislayedCount').innerHTML = count;
if (!count--) {
// count is zero, refresh weather info
// and start again
count = 10;
}
}, 1000);
},
stop: function() {
timerRef && clearInterval(timerRef);
timerRef = null;
}
};
}());
And some buttons to make it work (or start it when the page loads):
<button onclick="weatherRefresh.start();">Start</button>
<button onclick="weatherRefresh.stop();">Stop</button>
Note that the function will only run at about every second, if the system is busy it will not run on time and will slowly drift, but not by much each time, so it likely doesn't matter.
<script>
var timeone = 10;
setInterval(function () {
if (timeone <= 10 && timeone >= 0) {
document.getElementById("countdown").innerHTML = "Counting down from " +
timeone; }
if (timeone == 0) { timeone = 11; }
timeone--;
}, 500);
</script>
<div id="countdown"></div>