`appendChild` inside a `for` loop just replaces item created by `createElement`
Asked Answered
U

2

6

I Googled a lot about creating multiple items with appendChild, but I’m not understanding how it works. My appendChild just replaces instead of adding many.

var startGame;
var cards = 16;
var newDeck = [];

startGame = function(){
    var startBtn = document.getElementById('start');
    var board = document.getElementById('game-board');
    var backside = document.createElement("div");
    backside.className = 'card';

    startBtn.onclick = function(){
        removeButton = document.getElementById("start");
        removeButton.parentNode.removeChild(removeButton);

        for(var i = 0; i < cards; i++){ 
            board.appendChild(backside);
        }
    };
};

I also read you can do this with innerHTML, but that leaves me confused as well. Does anyone have a more detailed explanation on how to make this work?

Unalloyed answered 26/3, 2013 at 17:39 Comment(4)
It's not a replace, you're reusing the same created DOM node each time. You need to clone the node each time you want a new one. Or, as some of the answers state, make a new element within the loop.Eelworm
From the MDN documentation: "If child is a reference to an existing node in the document, appendChild moves it from its current position to the new position (i.e. there is no requirement to remove the node from its parent node before appending it to some other node)."Journalistic
@JaredFarrish I was just reading on elementObject.cloneNode(boolean);-way when you edited. I see if the object is created outside the loop you'd need to clone it. Thanks for a helpful answer too!Unalloyed
If you clone, just remember you need to make the id attribute unique for the clone.Eelworm
V
9

From the MDN on appendChild :

Adds a node to the end of the list of children of a specified parent node. If the node already exists it is removed from current parent node, then added to new parent node.

When you append an element that is yet in the DOM, you move it from its old place. Create the element in the loop :

startBtn.onclick = function(){
    removeButton = document.getElementById("start");
    removeButton.parentNode.removeChild(removeButton);

    for(var i = 0; i < cards; i++){ 
        var backside = document.createElement("div");
        backside.className = 'card';
        board.appendChild(backside);
    }
};
Vesuvianite answered 26/3, 2013 at 17:40 Comment(2)
Ah, I sorta understand the logic in that. Thanks :) once again the smart people of stackoverflow strikes !Unalloyed
30 mins of my life until I found this. Thanks.Haviland
H
2

I'm creating a single element and trying to re-add it multiple times, andI need to create multiple elements.

When I run document.createElement() to create an element, .appendChild() is just setting the location. So I created one element and then moved it to the same place many times. I want to instead create many elements and set their location once each.

var backside;
startBtn.onclick = function () {
  removeButton = document.getElementById("start");
  removeButton.parentNode.removeChild(removeButton);

  for (var i = 0; i < cards; i++) {
    backside = document.createElement("div");
    backside.className = "card";
    board.appendChild(backside);
  }
};

or alternatively (shorter but less flexible, only use this for a one-off)

startBtn.onclick = function () {
  removeButton = document.getElementById("start");
  removeButton.parentNode.removeChild(removeButton);

  for (var i = 0; i < cards; i++) {
    board.appendChild("<div class='card'></div>");
  }
};
Headphone answered 26/3, 2013 at 17:41 Comment(3)
I see, the second suggestion has more "ugly code" I suppose, its interesting to see how many ways you can solve this!Unalloyed
@Cammy Its ugly in the sense that you can't directly reference it or manipulate it. If you end up having to add more properties you have to edit the string or query for it again instead of using the reference. Nothing wrong with it for a one-off use though.Headphone
Yes thats how I meant! Thanks for the explanation :)Unalloyed

© 2022 - 2024 — McMap. All rights reserved.