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

javascript - Appending elements to DOM in a loop structure - Stack Overflow

programmeradmin1浏览0评论

Once the page has been loaded, I would like to append an additional element for each existing elements on the page.

I tried something like this:

    var divs=document.getElementsByTagName('div');

    for(i=0;i<divs.length;i++){
        newDiv=document.createElement('div');
        divs[i].appendChild(newDiv);
    }

Just a warning this will actually freezes the browser because the divs variable is dynamic and divs.length just gets larger and larger each time the loop goes.

Is there a way to determine the number of tags when the DOM is normally loaded for the first time and have a chance to work with the elements statically.

I can't there of another solution so far.

Thanks so much. Dennis!

Once the page has been loaded, I would like to append an additional element for each existing elements on the page.

I tried something like this:

    var divs=document.getElementsByTagName('div');

    for(i=0;i<divs.length;i++){
        newDiv=document.createElement('div');
        divs[i].appendChild(newDiv);
    }

Just a warning this will actually freezes the browser because the divs variable is dynamic and divs.length just gets larger and larger each time the loop goes.

Is there a way to determine the number of tags when the DOM is normally loaded for the first time and have a chance to work with the elements statically.

I can't there of another solution so far.

Thanks so much. Dennis!

Share Improve this question asked Jul 7, 2010 at 20:31 Dennis DDennis D 1,3434 gold badges17 silver badges24 bronze badges 2
  • 2 not the answer to your question but you should call var newDiv before the loop. Creating a variable without var makes a global variable. – jasongetsdown Commented Jul 7, 2010 at 20:45
  • not necessarily before the loop – Walter Macambira Commented Jun 21, 2017 at 13:28
Add a comment  | 

4 Answers 4

Reset to default 13

The problem is that DOM collections are live, and when the underlying document structure is changed, it will be reflected automatically on the collection, that's why when the length property is accessed it will contain a new length, a common approach is to cache the length before starting the loop:

var divs=document.getElementsByTagName('div');

for(var i = 0, len = divs.length;i<len;i++){
    var newDiv = document.createElement('div');
    divs[i].appendChild(newDiv);
}

Also notice that you should declare all your variables with the var statement, otherwise it might become global.

Edit: In this case, since you are appending child nodes of the same tagName, the collection will be modified, and the indexes will no longer match, after the first iteration, the index 1 will refer to the newDiv object from the previous iteration, as @Casey recommends it will be safer to convert the collection to a plain array before traversing it.

I use the following function:

function toArray(obj) {
  var array = [];
  // iterate backwards ensuring that length is an UInt32
  for (var i = obj.length >>> 0; i--;) { 
    array[i] = obj[i];
  }
  return array;
}

//...
var divs = toArray(document.getElementsByTagName('div'));
//...

Like you said, the divs variable is dynamic, so you have to convert it into an array (which is static) before you use it.

var nodeList = document.getElementsByTagName('div');
var divs = [];
for (var i = 0; i < nodeList.length; i++)
    divs.push(nodeList[i]);
// loop again and append the other divs

Another (more elegant) way to do this is:

var divs = Array.prototype.slice.call(document.getElementsByTagName('div'));

But alas, this method does not work in IE.

Using jQuery, this is pretty straight forward. You can get a reference to all the existing divs or any other element on the page and then append a new element very easily without needing to create an explicit loop. Hope this help.

$('div').each(function(){
   var newDiv = document.createElement('div');
   $(this).append(newDiv);
});

document.getElementsByTagName() does NOT return a plain array, but an instance of HtmlCollection, which behaves like an array, but in fact presents some kind of view to all elements with the given element name in the document.

So, whenever you insert something into the DOM, the length property of divs will be updated too - of course.

So, besides other answers here, this behaviour should make sense now ;-)

发布评论

评论列表(0)

  1. 暂无评论