BackUpUs1 BackUpUs1 - 5 months ago 15
Javascript Question

appendChild from childNodes doesn't work

This is an interesting question I saw on the net but didn't know the answer:

The following code is intended to add five identical boxes containing links to the document, but it doesn’t work properly. Why not?

// Copies the contents of one box into another
function copyContents(from, to){
for( var i=0; i<=from.childNodes.length-1; i++){
to.appendChild(from.childNodes[i]); // <---- Error on this line.
}
}

//create a box to copy:
var referenceBox = document.createElement('div');

var link = document.createElement('a');
link.href = 'http://www.example.com/';
link.textContent = 'A link';

referenceBox.appendChild(link);

//Add box copies to the document
for(var i=0; i<5; i++){
var newBox = document.createElement('div');
copyContents(referenceBox, newBox);

document.body.appendChild(newBox);
}


Options:


  1. to.appendChild() expects HTML, but from.childNodes[i] is a node object, so all the boxes will contain the texts[Object Node].

  2. document.createElement() reuses existing elements with the same tag, so only one box is added to the document.

  3. The same link element can’t have multiple parents,so only one box ends up with a link in it.

  4. A link’s href has to be set using setAttribute(); setting the property link.href won’t do anything,so none of the links in the boxes will point anywhere.



I guess the answer is 3, but not sure and don't know why?

Any explanation? Tnx

link: to the question

Answer

You should only iterate from i = 0 to childNodes.length - 1 in copyContent. Also, you should clone DOM nodes if you want to append them to multiple locations in your document (= 3rd option):

// Copies the contents of one box into another:
function copyContents(from, to) {
    for (var i = 0; i < from.childNodes.length; i++) { // <-- change <= to <
        to.appendChild(from.childNodes[i].cloneNode(true)); // <-- add cloneNode(true); to clone node and all its children
    }
}

// Create a box to copy:
var referenceBox = document.createElement('div');

var link = document.createElement('a');
link.href = 'http://www.example.com/';
link.textContent = 'A link';

referenceBox.appendChild(link);

// Add box copies to the document:
for (var i = 0; i < 5; i++) {
    var newBox = document.createElement('div');
    copyContents(referenceBox, newBox);

    document.body.appendChild(newBox);
}

See also appendChild only works first time