I've created a simple counter using javascript but there is a problem Field "display" starts from 1, but it should start from 100 and goes low. The console logs shows values correctly from 100 to 1.
I have to use loops to do this tasks, so please not replace it using recursion :) Also the timeout is for sure does not equal to 100ms, it's more
function wyswietlLiczbe(j) {
setTimeout(function() {
document.getElementById("display").innerHTML = j;
}, 100);
}
for (var i= 100; i > 0; i--){
console.log(i)
wyswietlLiczbe(i);
}
<p id="display"></p>
Since the loop executes immediately, you need to wait an increasing amount of time for each number. This will queue up the innerHTML modifications.
As it is now, after a 100ms wait all 100 wyswietlLiczbe are executed in rapid succession.
function wyswietlLiczbe(j, waitTime) {
setTimeout(function() {
document.getElementById("display").innerHTML = j;
}, waitTime);
}
for (var i= 100; i > 0; i--){
console.log(i)
wyswietlLiczbe(i, (101 - i) * 100);
}
<p id="display"></p>
Build the conditional into the function which will execute after the timeout.
var elmD = document.getElementById("display");
function wyswietlLiczbe(j) {
setTimeout(function() {
elmD.innerHTML = j;
j--;
if(0 <= j ) {
wyswietlLiczbe(j)
}
}, 100);
}
wyswietlLiczbe(100);
I don't know exactly what you want but I think this is what you're looking for.
function wyswietlLiczbe(j) {
if (j >= 0) {
setTimeout(function() {
document.getElementById("display").innerHTML = j;
j--;
wyswietlLiczbe(j);
}, 100);
}
}
wyswietlLiczbe(100);
<p id="display"></p>
you can use setInterval instead
function wyswietlLiczbe(j) {
x = setInterval(function() {
if(j==0) clearInterval(x);
document.getElementById("display").innerHTML = j--;
}, 100);
}
wyswietlLiczbe(100);
Related
If I use setTimeout in a loop so only after the loop ends it executes all the operation in the same time.
I tried to put setTimeout in a separate function, as suggested by many articles, but it does not help.
The code is very simple:
function foo(i)
{
setTimeout( function() {console.log(i);}, 2000);
}
for (let i=0; i<5; i++)
{
foo(i);
}
It prints
0
1
2
3
4
in one shot
It's because the proccess registry the 5 setTimeout at almost the same time.
Try with the different timeout time like this:
function foo(i)
{
setTimeout( function() {console.log(i);}, 1000 * i);
}
for (let i=0; i<5; i++)
{
foo(i);
}
you could also do it with a generator. a generator can pause midway through a function
https://www.javascripttutorial.net/es6/javascript-generators/
function* generator() {
let index = 1;
while (index <= 5) {
yield index++;
}
}
let f = generator();
var interval = window.setInterval(function(){
const obj = f.next();
if (obj.done){
clearInterval(interval);
} else {
console.log(obj.value)
}
}, 1000);
I'm trying to create an image slider for a website, I want to learn why my array won't go back to zero after finishing the first iteration and keep on iterating. I want the slider to iterate on and on automatically.
function run() {
for (let i = 0; i < imgArray.length; i++) {
(function(e) {
setTimeout(function() {
if (i == imgArray.length) {
i = 0;
}
imgContainer.style.background = imgArray[i];
}, 3000 * e);
})(i);
};
imgContainer.style.height = '100vh';
}
The condition i == imgArray.length inside the loop is never true, since the loop runs until i < imgArray.length. You could use <= instead as Ali Abug Hijleh suggested, but I think it would be easier to maintain if you explicitly show the loop should run forever with while (true) and use the % operator to get the right index:
function run() {
let i = 0;
while (true) {
(function(e) {
setTimeout(function() {
imgContainer.style.background = imgArray[i % imgArray.length];
}, 3000 * e);
})(i);
};
imgContainer.style.height = '100vh';
++i;
}
i will never reach the imgArray.length because the loop only works when i is less than imgArray.length (since you use i < imgArray.length as the condition)
Try if (i == imgArray.length -1) { ... } instead.
That's because your for loop ends before you reset it to zero because you reset it to zero inside a setTimeout
I'm trying to write a simple loop in JS (or JQuery) that updates an image every five seconds, for a total of 15 seconds (so three loops), and then quits.
It should go like this:
Wait five seconds
Execute
Wait five seconds
Execute
Wait five seconds
Execute
Quit
But setTimeout only seems to work once.
As a test, I've tried:
function doSetTimeout(i) {
setTimeout(function() { alert(i); }, 5000);
}
for (var i = 1; i <= 5; ++i)
doSetTimeout(i);
Does not work: http://jsfiddle.net/ubruksco/
I've also tried:
for(var i = 1; i <= 5; i++) {
(function(index) {
setTimeout(function() { alert(index); }, 5000);
})(i);
}
Does not work: http://jsfiddle.net/Ljr9fq88/
var time = 1;
var interval = setInterval(function() {
if (time <= 3) {
alert(time);
time++;
}
else {
clearInterval(interval);
}
}, 5000);
you can simply create an interval and kill it after the 3rd time
Your first example is nearly there. You just need to multiply the time delay by the loop index to get the right delay.
function doSetTimeout(i) {
setTimeout(function() { alert(i); }, 5000*i);
}
for (var i = 1; i <= 3; ++i)
doSetTimeout(i);
http://jsfiddle.net/ubruksco/3/
The reason is that your settimeout ends all at the same time (after 5 seconds) because your timeout code is based on 5 seconds
for(var i = 1; i <= 5; i++) {
(function(index) {
setTimeout(function() { alert(index); }, 5000);
})(i);
}
What you want to do is change the timeout time based on your index (hence will have different start times.
for(var i = 0; i < 3; i++) {
(function(index) {
setTimeout(function() { alert(index); }, index*5000);
})(i);
}
(Also needs 3 iterations, so edited out the loop for you)
You want setInterval() instead
setInterval(function(){ alert("Do Something"); }, 3000);
Make it easy! You do not need loop, you just need three executions.
setTimeout(function() { alert(1); }, 5000);
setTimeout(function() { alert(2); }, 10000);
setTimeout(function() { alert(3); }, 15000);
But, if you really want a loop:
function doSetTimeout(i) {
setTimeout(function() { alert(i); }, i*5000);
}
for (var i = 1; i <= 3; ++i)
doSetTimeout(i);
Assuming your are using jQuery (to manipulate the DOM),
you can try this:
['img1.jpg', 'img2.jpg', 'img3.jpg'].forEach(function(imgPath, index) {
// the callback will be executed in 5seconds * (index + 1)
setTimeout(function() {
// change image source
$('img#myImage').attr('src', imgPath);
}, 5000 * (index + 1));
});
With setTimeout:
function doSetTimeout(i) {
if(i >= 3) return;
alert(i);
setTimeout((function () {
return function () {
doSetTimeout(i);
};
})(i + 1), 5000);
}
doSetTimeout(0);
But you can also use setInterval, maybe more appropriate.
You can use setInterval instead and track how much times you have executed function. Than just use clearInterval() to stop execution.
var i = 1;
var interval = setInterval(function() {
execute();
}, 5000);
$(document).ready(function() {
execute();
});
function execute() {
$("#output").append("set<br/>");
if (i == 3) {
clearInterval(interval);
}
i++;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='output'></div>
If you want to first wait 5 secs, don't call execute() on domready.
I´m having trouble to delay a function in a for-loop.
So here is my test:
<script type="text/javascript">
var j = 0;
for(var i = 0; i <= 100; i++){
setTimeout(function(){
console.log(i);
},j*2);
j++;
}
</script>
I want that every count will appear step by step with a delay in the console. But currently only 101 appears 101 times. Why and what is a better solution?
Cheers
JavaScript doesn't have block level scoping of variables, so the value of i in any deferred functions will be the last value of i from the loop (in your case, 101). You can either use a named function or an immediately invoked function expression to create a closure that gives the value the correct scope.
<script type="text/javascript">
var j = 0;
for(var i = 0; i <= 100; i++){
(function(i) {
setTimeout(function(){
console.log(i);
},j*2);})(i);
j++;
}
</script>
Also bear in mind that the second argument passed to setTimeout is the delay in milliseconds, so that's a very short delay (a tiny fraction of a second) between each call.
function SetTimeoutLoop(i) {
setTimeout(function() { console.log(i); }, i*2);
}
for(var i = 0; i <= 100; i++){
SetTimeoutLoop(i)
}
JSFIDDLE
u may try this:
<script type="text/javascript">
var j = 0;
for(var i = 0; i <= 100; i++){
(function(i, j){
setTimeout(function(){
console.log(i);
},j*2);
})(i, j);
j++;
}
</script>
It happens as once your callback starts to fire your loop would be finished and the value will be max.
you can do like
(function me(i,j) {
if(i <= 10) {
setTimeout(function(){
alert(i++);
me(i,j);
},j++*2);
}
})(0,0);
Here is a sample fiddle.
You can't do that in for loop, instead you should use a recursive function like this:
here's a fiddle
var j = 0;
var i=0;
setTimeout(function(){
log_i(i);
},j*2);
function log_i(i){
console.log(i);
i++;
if(i<=100){
setTimeout(function(){ log_i(i); },j*2);
}
j++;
}
Completely stuck.
I have seen this popular solution for adding delays between iterations of a loop (https://stackoverflow.com/a/3583740), but it only seems to work for a single loop (i.e not nested).
This is the pseudo code,
for (var i = 0; i < max; i++){
for (var j = 0; j < max; j++){
pause(1000); // ideally would just elegantly pause all execution
}
}
I am trying to use setTimeout (unless other options exist!) but I can't seem to wrap my head around how to set it up.
Context - It should pause long enough for an animation to occur. (A different animation occurs depending on the values of i and j ).
As it has been said, you can't really pause execution in javascript. Though a trick could be to collect the instructions in a delayed queue which executes itself fifo. E.g.:
// helper function
var delayed = (function() {
var queue = [];
function processQueue() {
if (queue.length > 0) {
setTimeout(function () {
queue.shift().cb();
processQueue();
}, queue[0].delay);
}
}
return function delayed(delay, cb) {
queue.push({ delay: delay, cb: cb });
if (queue.length === 1) {
processQueue();
}
};
}());
your example, rewritten:
var i = 0, j, max = 3;
for (; i < max; i += 1) {
for (j = 0; j < max; j += 1) {
// add function to the queue, shadowing i/j with an IIFE:
delayed(1000, function(i, j) {
return function() {
console.log(i, j);
};
}(i, j));
}
}
demo: http://jsbin.com/kadepage/1/
This will work as nested for loop with delay.
var i = o = 0;
var max = 10;
var delay = 1000;
function rec()
{
console.log("outerloop"+o);
var inner = setInterval(function(){
console.log("innerloop"+i);
console.log(new Date());
i++;
if(i==max)
{
clearTimeout(inner);
var outer = setTimeout(function(){
o++;
i=0;
if(o==max)
{
return;
}
clearTimeout(outer);
rec();
},delay);
}
},delay);
}
rec();