I cant get my if statements to run it will only run the count down portion but the specifics like when it gets to 5 and 0 it just wont run those extra if statements.
function Countdown()
{
var currTime = 10;
var i = 10;
while (i>=0) {
if (currTime == 5)
{
setTimeout(function () {
document.getElementById("counter").innerHTML = "Warning Less than ½ way to launch, time left = " + currTime;
currTime = currTime - 1;
}, 1000 * i);
i -= 1;
}
if (currTime == 0)
{
document.getElementById("counter").innerHTML = "Blast OFF";
}
else
{
setTimeout(function () {
document.getElementById("counter").innerHTML = "the time left is " + currTime;
currTime = currTime - 1;
}, 1000 * i);
i -= 1; /* same as i = i-1 */
}
};
}
Actually your while loop execute the currTime 11 times here. The main issue is here you are using interval of 1 sec or 1 sec+ etc, but your loop runs very fast in ms of 100 or 500 which excecute currTime very fast. That's the issue here. I hope you got the issue.
Related
Basically I wanted to make a countdown with javascript, following my logic the code below should work, but for unknown reason it is not working. Could someone help me to figure out what's wrong with the code? It's kind of annoying.
function startCounter(time)
{
var counter= document.getElementById("counter").innerHTML;
var min=0;
setTimeout(function()
{
for(i = 0; i < time; i++)
{
document.getElementById("counter").innerHTML = min+ ":" +i;
if(i == 59) {
min++;
i = 0
document.getElementById("counter").innerHTML = min+ ":" +i;
}
}
}, 1000)
};
startCounter(89);
<p id="counter">0:00</p>
You are creating an infinite loop.
You are wrapping this part:
if(i == 59) {
min++;
i = 0
document.getElementById("counter").innerHTML = min+ ":" +i;
}
in a for loop that uses i as a limiter. Each time the i reaches 59, you are resetting it back to 0, and the loop continues.
// Add your code here
function startCounter(time)
{
var counter= document.getElementById("counter").innerHTML;
var min = parseInt(time / 60);
var seconds = time % 60;
setInterval(function()
{
seconds++;
document.getElementById("counter").innerHTML = min+ ":" +seconds;
if(seconds == 60) {
min++;
seconds = 0
document.getElementById("counter").innerHTML = min+ ":" +seconds;
}
}, 1000)
};
console.log("Start");
startCounter(89);
<p id="counter">
</p>
The issue is with this line:
for(i=0;i<time;i++) {
You have an infinite loop if your time is > 59, because of this line:
if(i==59){
//snip
i=0
}
Since your function is never finishing setTimeout is never finishing and the browser doesn't appear to be updating your element.
Don't set i back to zero, so your for(true) condition ist always true and your loop can't stop.
function startCounter(time)
{
var counter= document.getElementById("counter").innerHTML;
var min=0;
setTimeout(function()
{
for(i = 0; i < time; i++)
{
document.getElementById("counter").innerHTML = min+ ":" +i;
if(i == 59) {
min++;
document.getElementById("counter").innerHTML = min+ ":" +i;
}
}
}, 1000)
};
startCounter(89);
<p id="counter">0:00</p>
var timer;
var i = 0;
var counter = document.getElementById("counter");
var min = 0;
var targetTime = 5;
function startCounter(){
if(min < targetTime){
if(i == 59){
min++;
i = "00";
} else {
i++;
if (i < 10) {
i = "0"+i;
}
}
counter.innerHTML = min + ":" + i;
} else {
clearInterval(timer);
}
}
timer = setInterval(startCounter, 1000);
<p id="counter"></p>
You have a couple of problems... you seem to be trying to iterate seconds inside the callback that will be executed once every second.
Even if you fixed that code, you're going to have a problem with the fact that setTimeout does not execute exactly at the specified value. It fires whenever the thread can queue the task > the time scheduled. So your timer is going to drift over it's duration.
I'd recommend the below approach. Using a requestAnimationFrame loop (you could also use an interval) check the difference in the JavaScript clock between the time you started and now and then print the difference.
var firstTime;
function startTimer(){
firstTime = Date.now();
runTimer();
}
function runTimer(){
var diff = Date.now() - firstTime;//value in milliseconds since the timer started.
var sec = Math.floor((diff/1000)) % 60;//constrain to seconds
var min = Math.floor(diff/(1000 * 60));//minutes
document.getElementById('timer').innerHTML = min + ":"+(String(sec)).padStart(2,"0");
requestAnimationFrame(runTimer);
}
startTimer();
<div id="timer">0:00</div>
You have a couple options that would work. Calling the startCounter again from inside your setTimeout function or my favourite way is window.setInterval.
var p = document.getElementById("count");
function startTimer(time){
var num = 0; // the increment number
var intervalId = window.setInterval(function(){
num += 1; // increment the number
if(num == time){
window.clearInterval(intervalId);
// you can run your callback here after the timer reached your goal
startTimer(num + 1); // this just adds a second and restarts the timer as a example
}
p.innerText = num;
}, 1000);
}
// Start the timer here
startTimer(10);
<p id="count"></p>
I am trying to make a JS counter to reach a random number and reset it self once it reaches the number and repeat again in 5 seconds.
For example: Random Number is 0.05.
0.00 > 0.01 > 0.02 > 0.03 > 0.04 > 0.05 > 0.00
<div id="current">0</div>
JS
var randomNum = Math.random();
if ( current <= randomNum ) {
for (current = 0; current < randomNum; current+=0.01) {
setInterval(function(){
current += .01;
},1000); } }
else {
current = 0;
}
You could use a closure over the variables and make a check inside of the callback, if greater then the wanted result.
This proposal uses setInterval for counting and setTimeout for the waiting time of 5 sec and the restarting with a new random value.
function startInterval() {
var randomNum = Math.floor(Math.random() * 8) + 2,
current = 0,
interval = setInterval(function() {
current += .01;
if (current > randomNum / 100) {
current = 0;
clearInterval(interval);
setTimeout(startInterval, 5000);
}
document.getElementById('current').innerHTML = current.toFixed(2);
}, 1000);
}
startInterval();
<div id="current">0</div>
Keep a counter variable outside of the loop and then simply clear it, when the desired value is reached.
var randomNum = Math.random() * 25;
var currentValue = 0;
var counter;
counter = setInterval(function() {
if (currentValue < randomNum) {
//Carefull with "0.1" as JavaScript doesn't like it!
currentValue = (currentValue * 10 + 1) / 10
}
if (currentValue > randomNum) {
currentValue = randomNum;
clearInterval(counter);
}
console.log(currentValue, '/', randomNum)
}, 1000 / 60)
I want to create a delay in a loop depending on a condition. Say, I have this:
var maxLoops = 50;
var counter = 0;
(function next() {
if (counter++ >= maxLoops) {
return;
}
setTimeout(function() {
console.log(counter);
next();
}, 100);
})();
Is there any way to pause the process for 2 seconds only when the counter is equal to 10, 20 or 30? So it should print:
1....10
(delay for a custom period of time)
11....20
(delay for a custom period of time)
21....30
(delay for a custom period of time)
31...50
The bottom line is, I don't want to delay at all when the counter isn't equal to 10, 20, 30.
Sure you can do that just change the timeout when you have a multiple of 10.
var maxLoops = 50;
var counter = 0;
(function next() {
counter += 1
var timeout_duration = counter % 10 == 0 ? 2000 : 0;
if (counter >= maxLoops) {
return;
}
setTimeout(function() {
console.log(counter);
next();
}, timeout_duration);
})();
That said, there need some few improvments because maxLoops and counter are defined on the global scope. Make it a function.
function loop (maxLoops, start) {
var counter = start || 0;
(function next() {
counter += 1
var timeout_duration = counter % 10 == 0 ? 2000 : 100;
if (counter >= maxLoops) {
return;
}
setTimeout(function() {
console.log(counter);
next();
}, timeout_duration);
})();
}
loop(50);
If you don't want to call next when counter isn't a multiple of 10, then you can add a usual loop in between the calls.
function loop (maxLoops, start) {
var counter = start || 0;
var timeout_duration = 2000;
(function next() {
while(counter < maxLoops && counter % 10 != 0) {
counter += 1
}
if (counter >= maxLoops) {
return;
}
setTimeout(function() {
console.log(counter);
next();
}, timeout_duration);
})();
}
loop(50);
That said, keep in mind that a setTimeout of 2000 doesn't mean exactly 2 seconds, but not less than 2 seconds. If somehwere, there is a loop that breaks the thread, the setTimeout could be never called as Javascript is single threaded and there is no fact that the function will be called after 2 seconds. If you're planning to use setTimeout to measure something within time, you might have to plan something else that will include the Date object for timings.
You can just use the setTimeout() with a different timing based on your counter:
var maxLoops = 50;
var counter = 0;
(function next() {
if (counter++ >= maxLoops) {
return;
}
var delay = 0;
// on multiples of 10, use a longer counter
if (counter % 10 === 0) {
delay = 2000;
}
setTimeout(function() {
console.log(counter);
next();
}, delay);
})();
Or, you could skip the setTimeout() completely when you don't need the delay.
var maxLoops = 50;
var counter = 0;
(function next() {
if (counter++ >= maxLoops) {
return;
}
// on multiples of 10, use a longer counter
if (counter % 10 === 0) {
setTimeout(function() {
console.log(counter);
next();
}, 2000);
} else {
console.log(counter);
next();
}
})();
Or, rather than recursion, you can just use a while loop as in this working snippet:
var maxLoops = 50;
var counter = 0;
(function next() {
// while we haven't hit maxLoops and while not a multiple of 10
while (counter < maxLoops && counter % 10 !== 0 && counter !== 0) {
log(counter);
++counter;
}
if (counter < maxLoops) {
setTimeout(function() {
log(counter);
++counter;
next();
}, 1000);
}
})();
function log(x) {
var div = document.createElement("span");
div.innerHTML = x + " ";
document.body.appendChild(div);
}
I am aiming for a loading progress bar that fluctuates in speed as it goes from 0 to 100%. I would like some variety in the way it loads to give the appearance of loading my app. The following code sorta gets me there, but just not with the variety I was looking for.
Any suggestions on how to improve upon or completely reconstruct this?
UPDATE:
I have altered the code myself to achieve what I'm looking for.
Here's a fiddle: JSFIDDLE
var counter = 0; var factor = 1;
var timer = setInterval(function () { // timer function for progress bar
counter = counter + factor;
$('.progressbar').val(counter);
if (counter >= 10 && counter <= 59) {
damping = Math.floor(Math.random() * (300 - 25)) + 6;
factor = Math.max((100 - counter) / damping, '0.5');
} else if (counter >= 60 && counter < 100) {
damping = Math.floor(Math.random() * (50 - 25)) + 3;
factor = Math.max((100 - counter) / damping, '0.5');
} else if (counter > 100) {
clearInterval(timer);
};
}, 30);
Why the following code prints "0 5 10 15 20 ... 100"?
(function () {
for ( var i = 100; i >= 0; i -= 5) {
(function() {
var pos = i;
setTimeout(function() {
console.log(" pos = " + pos);
}, (pos + 1)*10);
})();
}
})();
I declare pos = i , which should be in a descending order. This code originated from John Resig' fadeIn() function in his book Pro javascript techniques.
You're registering the timeouts in the correct order, the problem is they're timed in order of their value, so value 10 will be printed in 100ms, value 100 in 1000ms, etc.
So you need to change the timing calculation to subtract from the max value (in this case, 100)
(function () {
for ( var i = 100; i >= 0; i -= 5) {
(function() {
var pos = i;
setTimeout(function() {
console.log(" pos = " + pos);
}, (100 - pos + 1)*10); // note the subtraction here
})();
}
})();