3

I want to create 1 div container every x second. And I want to do this n times.

So I started creating this

$(document).ready(function() {
  for (var i = 0; i < 5; i++) {
    createEle(i);
  }
});

function createEle(value) {
  var d = $("<div></div>");
  d.addClass("d");
  d.html(value);
  $("#container").append(d);
}
.d {
  height: 20px;
  color: white;
  background: red;
  margin-bottom: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">

</div>

this works fine. But I want to integrate the time interval.

$(document).ready(function() {
  for (var i = 0; i < 5; i++) {
    setTimeout(function() {
      createEle(i);
    }, i * 1000);
  }
});

function createEle(value) {
  var d = $("<div></div>");
  d.addClass("d");
  d.html(value);
  $("#container").append(d);
}
.d {
  height: 20px;
  color: white;
  background: red;
  margin-bottom: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">

</div>

As you can see in the second example, I always get the wrong value because it passes in the wrong index value.

How can I fix that?

peterHasemann
  • 1,550
  • 4
  • 24
  • 56

3 Answers3

4

Replace var with let.

for (let i = 0; i < 5; i++) {

Demo

$(document).ready(function() {
  for (let i = 0; i < 5; i++) {
    setTimeout(function() {
      createEle(i);
    }, i * 1000);
  }
});

function createEle(value) {
  var d = $("<div></div>");
  d.addClass("d");
  d.html(value);
  $("#container").append(d);
}
.d {
  height: 20px;
  color: white;
  background: red;
  margin-bottom: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">

</div>

Reason

var doesn't let go of the bindings of the parent lexical-environment hence its hoisted value is retained in the asynchronous callback handler (of setTimeout), however let doesn't hold on to the bindings of any lexical-environment other than its own current one.

gurvinder372
  • 66,980
  • 10
  • 72
  • 94
1

please update your code. no need of for loop.

var i=1;
$(document).ready(function() {

  setInterval(function() {
      createEle(i);
    }, i * 1000);
});

function createEle(value) {
  var d = $("<div></div>");
  d.addClass("d");
  d.html(value);
  $("#container").append(d);
  i++;
}
Negi Rox
  • 3,828
  • 1
  • 11
  • 18
1

Loop will completely executed before the first setTimeout runs. So the value of the i will be 5

Treat setTimeout and setInterval as a asynchronous function.

$(document).ready(function() {
  var i = 0;
  var tmer = setInterval(function() {
    createEle(i);
    i = i + 1;
    if(i==5)
      clearInterval(tmer);
  }, 1000);

});

function createEle(value) {
  var d = $("<div></div>");
  d.addClass("d");
  d.html(value);
  $("#container").append(d);
}
.d {
  height: 20px;
  color: white;
  background: red;
  margin-bottom: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">

</div>
Sankar
  • 6,908
  • 2
  • 30
  • 53