When you press the div.help button (height = 0), it "leaves" down; when you press the same button, it collapses. I decided to combine all this in one cycle. Well, diva leaves, but when you click again he leaves the starting position! For some reason, in the closure height is not saved, but takes the initial value.
Here is:

someButton.onclick = showHelp; var display = document.getElementsByClassName("help")[0]; var height = 0; // начальное значение 0, такое же прописано и в css function showHelp(){ // делаем хитрость: изначально h1=0, h2=150, step=1, // при повторном клике значения меняются! - h1=150, h2=0, step=-1 // цикл в каждом из случаев то наращивается до 150, то снова опускается до 0 var h1,h2,step; h1 = height; h2 = height = Math.abs(height*1 - 150); step = (h2-h1)/Math.abs(h2-h1); console.log(h1,h2,step); // проверяем. Действительно это работает for (i = h1; i != h2 ; i = i + step){ (function(){ var ii = i;// замыкаем значение каждого из i setTimeout(function(){ display.style.height = ii + "px"; },(ii+1)*5); })(); } } 

Everything is almost perfect. The closure works correctly. ii takes values ​​from 0 to 150, then from 150 to 0. However, display.style.height somehow increases from 0 to 150 each time, and that's it. Maybe I missed some trifle? I do not understand anything. After all, style.height can not be some local property ...

    1 answer 1

    All because of the time in setTimeout(...,(ii+1)*5); you have it depends on the value of ii and even with the reverse order of definition, the order of calls itself will not change. In this case, the total does not change from rearrangement of places; these two calls will give the same result:

     //Вызов 1 function(){ display.style.height = 150 + "px"; },(150+1)*5) ... function(){ display.style.height = 1 + "px"; },(1+1)*5) //Вызов 2 function(){ display.style.height = 1 + "px"; },(1+1)*5) ... function(){ display.style.height = 150 + "px"; },(150+1)*5) 

    It is necessary to change the order, well, to vskidku:

      ... j = 0; for (i = h1; i != h2 ; i = i + step){ j++; (function(){ var ii = i;// замыкаем значение каждого из i setTimeout(function(){ display.style.height = ii + "px"; console.log((ii+1)*5); },(j+1)*5); })(); } ... 

    And everything will work as it should.

    • @Alex Krass, I knew that some invisible trifle ... Thank you! Tell me, in such cases is it more appropriate to use setInterval? - Deus
    • @Deus, I won’t say without thinking if you can successfully setInterval here. - Alex Krass