I want to append child div to each given parent divs. The child div supposed to be decorated by calling decorateDiv().
For example, after the appendChildren is executed, following divs should take the following form (assuming decorateDiv does nothing)
function appendChildren()
{
var allDivs = document.getElementsByTagName("div");
for (var i = 0; i < allDivs.length; i++)
{
var newDiv = document.createElement("div");
decorateDiv(newDiv);
allDivs[i].appendChild(newDiv);
}
}
// Mock of decorateDiv function for testing purposes
function decorateDiv(div) {}
what am i doing wrong?
I want to append child div to each given parent divs. The child div supposed to be decorated by calling decorateDiv().
For example, after the appendChildren is executed, following divs should take the following form (assuming decorateDiv does nothing)
function appendChildren()
{
var allDivs = document.getElementsByTagName("div");
for (var i = 0; i < allDivs.length; i++)
{
var newDiv = document.createElement("div");
decorateDiv(newDiv);
allDivs[i].appendChild(newDiv);
}
}
// Mock of decorateDiv function for testing purposes
function decorateDiv(div) {}
what am i doing wrong?
Share Improve this question asked Apr 13, 2015 at 12:59 ShaonlineShaonline 1,6376 gold badges19 silver badges37 bronze badges 2 |3 Answers
Reset to default 10You're running into the fact that .getElementsByTagName()
returns a live NodeList. That means that the new <div>
elements that you're adding to the page become part of the list as soon as you do so.
What you can do is turn that NodeList into a plain array beforehand:
var allDivs = document.getElementsByTagName("div");
allDivs = [].slice.call(allDivs, 0);
Now using "allDivs" in the loop will just append your new elements into the ones that were there when you originally went looking for them.
Using the allDivs.length
in the condition
field will accesses the length
property each time the loop iterates. So declare a variable for the length
outside the function and specify the variable name in the condition
field.
function appendChildren()
{
var allDivs = document.getElementsByTagName("div");
var len = allDivs.length;
for (var i = 0; i < len ; i++)
{
var newDiv = document.createElement("div");
decorateDiv(newDiv);
allDivs[i].appendChild(newDiv);
}
}
// Mock of decorateDiv function for testing purposes
function decorateDiv(div) {}
getElementsByTagName
returns Live NodeList
, which keeps the length increasing for every new div added.
Either use document.querySelectorAll()
which is Not a Live NodeList
.
let allDivs = document.querySelectorAll("div");
or Convert the Live NodeList to array. With ES6 [...spread] operator its really simple.
let allDivs = [...document.getElementsByTagName("div")];
newDiv = decorateDiv(newDiv);
then in yourdecorateDiv()
method returnnewDiv
– brso05 Commented Apr 13, 2015 at 13:02