Basic JS question: delay per iteration?

So what I thought was a simple and common goal of being able to grow and shrink the height of a div/page turned out to be the opposite, which makes me question if the method I am using is correct.

I have a div that takes up 100% width and height, and I want some type of animated welcome page of some sorts.

So I tried using a simple js function:

    for(var i = 0; i<=100; i++){
        setInterval(
            function(){
                var test =$('#bg0');
                test = test.css("height", i + "%");
            }, 1000
        );
    }

I have no idea why this doesn’t work, I assumed that this use case is the entire purpose of the setInterval function.

The most concerning part for me is this… I found the solution but I almost wish I didn’t. I have no idea how this works and it’s kind of melting my mind.

The article I ripped the code from says it uses an Immediate Invoking Function Expression(IIFE) but that’s pretty much the extent of the explanation

The first perplexing part for me is obviously using i as an argument in the IIFE function, what is this actually doing? Creating a function for every iteration?

But the most mind melting part is the i variable being multiplied by the timeout duration at the end of the anon function … wouldn’t that result in an exponentially increased time?

This code seems like black magic, I would greatly appreciate anyone’s attempt in elucidating this for me.

Thanks in advance

    for(var i = 0; i<=100; i++){
        (function(i){
            setTimeout(
                function(){
                    var test =$('#bg0');
                    test = test.css("height", i + "%");
                }, 10*i
            );
        })(i);   
    }

So I’ve set this to “watching” because I’m kind of interested in the actual answer, but from what I can tell, it’s got something to do with how setTimeout works in regards to the order of things on the execution stack, kind of like what’s mentioned here: https://stackoverflow.com/questions/14863022/settimeout-behaviour-with-blocking-code
but I don’t have a more exact answer than that. Wouldn’t setInterval make more sense for this sort of time sensitive, iterative thing?

1 Like

This can be rewritten this way, so it will make more sense for you.

for (var i = 0; i <= 100; i++) {
    function wait(i) {
        var test = $('#bg0');
        test = test.css("height", i + "%");
    }
    wait(i)
}

If you add this wait function to setTimeout function, it will pause before executing the wait function.

1 Like

The reason your original code did not appear to work is that the for loop finishes those 100 iterations before the first setInterval executes. setInterval is asynchronous so let’s other synchronous code run and does not hold up anything. When the setInterval executes (and continues to execute), i is already 100, so after each 1000ms of time that passes, you are essentially executing:

test = test.css("height", 101 + "%");

The main purpose is to isolate the variable i so that when the function executes, the value of i at the time the function was executed is kept (i.e. closure).

Also, I assume you don’t really want to use setInterval here because this would run forever and you only want to run it 100 times. With a couple slight modifications to your original code (using let instead of var and using setTimeout), you can accomplish what you want.

for (let i = 0; i < 100; i++) {
  setTimeout(
    function() {
      let test =$('#bg0');
      test = test.css("height", i + "%");
    }, 10 * i
  );
}

The 10 * i allows you to see the affect of the height change every 1/10 of a second until a height of 100% is reached.

2 Likes

Thank you, that is a much better approach than how I was doing it.

Your explanation was perfect and answered all of my questions. I really appreciate it!!

The code works almost perfectly but why i can’t change the iteration number (100) to a variable? I don’t wan’t to hardcode it but it doesn’t work with a variable unfortunately. :frowning: Thank you in advance.

It will work with a variable. Make sure it is defined before the loop and is a number.

Post a short snip-it of your code if still having issues.

Yes, you are right it really works. It was only my mistake, I gave the length after my variable name which is just an integer :smiley: