最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - appending child div to each div with for loop - Stack Overflow

programmeradmin2浏览0评论

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
  • You might want to return the decorated div like newDiv = decorateDiv(newDiv); then in your decorateDiv() method return newDiv – brso05 Commented Apr 13, 2015 at 13:02
  • 1 He doesn't need to, elements are live nodes. Modifications made within decorateDiv apply to the element even if it isn't returned. – Domino Commented Apr 13, 2015 at 13:08
Add a comment  | 

3 Answers 3

Reset to default 10

You'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")];
发布评论

评论列表(0)

  1. 暂无评论