0

I am working on a solution for the "looping a triangle" exercise at the end of Eloquent JavaScript ch2. The book asks to log output to the console but I want to print the output to a webpage instead, in a div with id="triangle".

This code is printing the right number of hashes. The problem is that the
tag that is created within the for loop is mysteriously removed when the loop increments in the final expression. That is: if I step through the code hashPrint.appendChild(carriage) executes fine at the breakpoint, but once the debugger gets to i++ the
child element is removed from the web page.

var hash = "";
var hashPrint = document.getElementById("triangle");
var carriage = document.createElement("br");

for (var i = 0; i < 7; i++) {
    hash += "#";
    var content = document.createTextNode(hash);
    hashPrint.appendChild(content); 
    hashPrint.appendChild(carriage);
}

If I put the var carriage declaration within the for loop it works fine. I know that JS best practice encourages avoiding global scope, I've been doing a lot of Java programming lately and it seemed to me that having the createElement("br") in global might be handy if I want to use it in another loop on the page.

Even though I already have a solution for the issue, I'd like to know why the final expression on the for loop would trigger the removal of the child node. Basically, why doesn't this work? I have searched high and low for an explanation with no luck.

alodrummer
  • 11
  • 1
  • 4

2 Answers2

1

because you are appending the same element so it replaced itself each time you use it. You need to create a new one for each time you use it.

for (var i = 0; i < 7; i++) {
  hash += "#";
  var content = document.createTextNode(hash);
  hashPrint.appendChild(content);
  var carriage = document.createElement("br");
  hashPrint.appendChild(carriage);
}
epascarello
  • 204,599
  • 20
  • 195
  • 236
  • I'm also not sure if you can add multiple textNodes to the same element – Jonathan May 07 '18 at 19:40
  • Yes, I had this same code working and was wondering why the code in my example didn't work. I think I understand. By declaring the node outside the loop it is only created once, then moved in the DOM by appendChild() after every iteration of the loop. I still think it's strange that the node is removed on the increment, and then not replaced until the method is called again. – alodrummer May 10 '18 at 15:23
0

Try cloning the node or appendChild() will eat it:

var hash = "";
var hashPrint = document.getElementById("triangle");
var carriage = document.createElement("br");

for (var i = 0; i < 7; i++) {
    hash += "#";
    var content = document.createTextNode(hash);
    hashPrint.appendChild(content); 
    hashPrint.appendChild(carriage.cloneNode(true));
}

See: https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild

or, Why does cloneNode need to be used when appending a documentFragment?

Jonathan Rys
  • 1,782
  • 1
  • 13
  • 25