在循环结构中将元素附加到DOM

Den*_*s D 3 javascript dom

页面加载后,我想为页面上的每个现有元素添加一个额外的元素.

我试过这样的事情:

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

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

只是一个警告,这实际上会冻结浏览器,因为divs变量是动态的,每次循环时divs.length只会越来越大.

有没有办法确定DOM第一次正常加载时的标签数量,并有机会静态处理这些元素.

到目前为止,我无法解决另一种解决方案.

非常感谢.丹尼斯!

CMS*_*CMS 11

问题是DOM集合是实时的,当底层文档结构发生变化时,它会自动反映在集合上,这就是为什么当length访问该属性时它将包含一个新的长度,一种常见的方法是在之前缓存长度开始循环:

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

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

另请注意,您应该使用var语句声明所有变量,否则它可能会变为全局变量.

编辑:在这种情况下,由于您要附加相同tagName的子节点,因此将修改集合,并且索引将不再匹配,在第一次迭代之后,索引1将引用newDiv上一次迭代中的对象,如@ Casey建议在遍历它之前将集合转换为普通数组会更安全.

我使用以下功能:

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'));
//...
Run Code Online (Sandbox Code Playgroud)