Souljacker
Souljacker

Reputation: 595

Can't multiple append() within a for loop

I'm trying to use the following code to append 40 new div elements to a #colors div:

$( document ).ready(function() {
    var $node = $("<div></div>");
    var $divg = $('#colors');
    for (var i = 1; i <= 40; i++) {
        $divg.append($node);
    }
});

At the end I get the following:

<div id="colors">
    <div></div>
</div>

Could someone please tell me what's happening?

I can't figure out.

Upvotes: 0

Views: 2518

Answers (4)

zer00ne
zer00ne

Reputation: 44118

I used plain JavaScript (I wrapped it in a $(function(){}), because I was going to write jQuery initially.)because (at least for me) it's easier to read the code (plus I suck at jQuery too many options makes my mind lazy.)

Although cloning is the common way to accomplish your goal, there are other ways to iterate through the creation of elements such as createElement() and appendChild();

$(function() {
  for (var i = 0; i < 40; i++) {
    var shade = document.getElementById('colors');
    var x = document.createElement('div');
    x.classList.add('x');
    shade.appendChild(x);
  }
});
#colors {
  border: 3px inset black;
  min-height: 30px;
  max-width: 300px;
  display: table;
}
.x {
  border: 1px solid red;
  min-width: 30px;
  border-radius: 50%;
  display: table-cell;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>


<div id="colors">
  <div></div>
</div>

Upvotes: 2

rrk
rrk

Reputation: 15875

I cannot explain it better that T.J's explanation. Use the clone() function to create a new div.

$( document ).ready(function() {
    var $divg = $('#colors');
    var $node = $("<div></div>");
    for (var i = 1; i <= 40; i++) {
        $divg.append($node.clone());
    }
});
#colors div{
  border : 1px solid red;
  width : 50px;
  height : 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="colors">
    <div></div>
</div>

Upvotes: 2

T.J. Crowder
T.J. Crowder

Reputation: 1075925

When you do var $node = $("<div></div>"); you're creating a jQuery object with a newly-created div inside it which isn't in the DOM yet. The first time you append it, you put it in the DOM. The second time you append it, you move it. (Well, you would if you were appending it to something else, but actually you're just putting it in the same place.)

If you want multiple divs, you need to create more than one. clone does that, but in that code, you could just do it directly.

Append is perfectly happy with markup:

$( document ).ready(function() {
    var $divg = $('#colors');
    for (var i = 1; i <= 40; i++) {
        $divg.append("<div></div>");
    }
});

Or if it's important to create the element first because you're doing things with it:

$( document ).ready(function() {
    var $node;
    var $divg = $('#colors');
    for (var i = 1; i <= 40; i++) {
        $node = $("<div></div>");
        $divg.append($node);
    }
});

Or using clone, but in this case I probably wouldn't:

$( document ).ready(function() {
    var $node = $("<div></div>");
    var $divg = $('#colors');
    for (var i = 1; i <= 40; i++) {
        $divg.append($node.clone());
    }
});

(Note that technically, that creates an extra div, but it's fine, that isn't expensive and it doesn't get added to the DOM anywhere.)

Upvotes: 2

Gavriel
Gavriel

Reputation: 19247

move var $ node = .. .into the loop:

$( document ).ready(function() {
    var $divg = $('#colors');
    for (var i = 1; i <= 40; i++) {
        var $node = $("<div></div>");
        $divg.append($node);
    }
});

or even:

 $divg.append("<div></div>");

Upvotes: 1

Related Questions