How to add multiple divs with appendChild?
Asked Answered
S

4

47

I am trying to make a chessboard using javascript and creating 64 divs with it.
The problem is, that it creates only the first div.
Here is the code:

div {
    width: 50px;
    height: 50px;

    display: block;
    position: relative;
    float: left;
}

<script type="text/javascript">
    window.onload=function()
    {
        var i=0;
        var j=0;
        var d=document.createElement("div");

        for (i=1; i<=8; i++)
        {
            for (j=1; j<=8; j++)
            {
                if ((i%2!=0 && j%2==0)||(i%2==0 && j%2!=0))
                {
                    document.body.appendChild(d);
                    d.className="black";
                }
                else
                {
                    document.body.appendChild(d);
                    d.className="white";
                }
            }
        }
    }
</script>
Shamblin answered 16/2, 2013 at 12:17 Comment(0)
H
33

The problem is, that it creates only the first div.

Right, because you've only created one div. If you want to create more than one, you must call createElement more than once. Move your

d=document.createElement("div");

line into the j loop.

If you call appendChild passing in an element that's already in the DOM, it's moved, not copied.

window.onload=function()
    {
        var i=0;
        var j=0;

        for (i=1; i<=8; i++)
        {
            for (j=1; j<=8; j++)
            {
                if ((i%2!=0 && j%2==0)||(i%2==0 && j%2!=0))
                {
                    var d=document.createElement("div");
                    document.body.appendChild(d);
                    d.className="black";
                }
                else
                {
                    var d=document.createElement("div");
                    document.body.appendChild(d);
                    d.className="white";
                }
            }
        }
    }
Hypsography answered 16/2, 2013 at 12:19 Comment(2)
@SvyatoslavSykalo: Good deal, glad that helped!Hypsography
Note this approach will cause page reflow (computation of element's position and geometry) every time you call appendChild(). Use documentFragment (see below) to batch append child.Calculating
C
78

As t-j-crowder has noted, the OP's code only creates one div. But, for googlers, there is one way to append multiple elements with a single appendChild in the DOM: by creating a documentFragment.

function createDiv(text) {
  var div = document.createElement("div");
  div.appendChild(document.createTextNode(text));
  return div;
}

var divs = [
  createDiv("foo"),
  createDiv("bar"),
  createDiv("baz")
];

var docFrag = document.createDocumentFragment();
for(var i = 0; i < divs.length; i++) {
  docFrag.appendChild(divs[i]); // Note that this does NOT go to the DOM
}

document.body.appendChild(docFrag); // Appends all divs at once
Christly answered 16/2, 2013 at 12:29 Comment(2)
Thanks! Interesting, i'll try this one too.Shamblin
You should always go with documentFragment when adding multiple elements. documentFragment acts as a staging area where you repeatedly add elements and, at last, you add it to the DOM. Repeatedly adding elements to the DOM will cause entire document reflow. See this: ejohn.org/blog/dom-documentfragmentsDiscarnate
H
33

The problem is, that it creates only the first div.

Right, because you've only created one div. If you want to create more than one, you must call createElement more than once. Move your

d=document.createElement("div");

line into the j loop.

If you call appendChild passing in an element that's already in the DOM, it's moved, not copied.

window.onload=function()
    {
        var i=0;
        var j=0;

        for (i=1; i<=8; i++)
        {
            for (j=1; j<=8; j++)
            {
                if ((i%2!=0 && j%2==0)||(i%2==0 && j%2!=0))
                {
                    var d=document.createElement("div");
                    document.body.appendChild(d);
                    d.className="black";
                }
                else
                {
                    var d=document.createElement("div");
                    document.body.appendChild(d);
                    d.className="white";
                }
            }
        }
    }
Hypsography answered 16/2, 2013 at 12:19 Comment(2)
@SvyatoslavSykalo: Good deal, glad that helped!Hypsography
Note this approach will cause page reflow (computation of element's position and geometry) every time you call appendChild(). Use documentFragment (see below) to batch append child.Calculating
M
12

Although what T.J. Crowder writes works fine, I would recommend rewriting it to the code below, using a documentFragment, like Renato Zannon suggested. That way you will only write to the DOM once.

    window.onload = function() {
        var count = 5,
            div,
            board = document.getElementById('board'),
            fragment = document.createDocumentFragment();
        
        // rows
        for (var i = 0; i < count; ++i) { 

            // columns
            for (var j = 0; j < count; ++j) { 
                div = document.createElement('div');
                div.className = (i % 2 != 0 && j % 2 == 0) || (i % 2 == 0 && j % 2 != 0) ? 'black' : 'white';
                fragment.appendChild(div);
            }
        }
        
        board.appendChild(fragment);
    };
#board {
  background-color: #ccc;
  height: 510px;
  padding: 1px;
  width: 510px;
}

.black,
.white {
    float: left;
    height: 100px;
    margin: 1px;
    width: 100px;
}

.black {
  background-color: #333;
}

.white {
  background-color: #efefef;
}
<div id="board"></div>
Missile answered 3/11, 2013 at 22:45 Comment(0)
V
1
function crt_dv(){
dv=document.createElement('div'),document.body.appendChild(dv)
};

crt_dv(),dv.className='white';crt_dv(),dv.className='black';

Also use: for(i=0;i<2;i++)

Vierra answered 29/4, 2016 at 11:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.