Javascript 向dom添加元素数组

Javascript 向dom添加元素数组,javascript,Javascript,我用HTML创建了5个div,我想将它们全部添加到我用JavaScript创建的div包装中。我尝试通过for in循环遍历5div,然后将div作为包装器的子项追加 由于某种原因,For循环会更改5div的顺序,并且不会将它们全部附加到包装器中。如何使用JavaScript将所有div添加到wrapper,保持(HTML)顺序 (请不要发布JQuery答案,因为这不是问题所在。我只想要JavaScript答案,) var wrapper=document.createElement('di

我用HTML创建了5个
div
,我想将它们全部添加到我用JavaScript创建的
div
包装中。我尝试通过
for in
循环遍历5
div
,然后将
div
作为
包装器的子项追加

由于某种原因,
For
循环会更改5
div的
顺序,并且不会将它们全部附加到
包装器中。如何使用JavaScript将所有
div
添加到
wrapper
,保持(HTML)顺序

(请不要发布JQuery答案,因为这不是问题所在。我只想要JavaScript答案

var wrapper=document.createElement('div'),
myClass=document.getElementsByCassName('myClass');
myClass[0]。parentElement.appendChild(包装器);
wrapper.id='wrapper';
for(myClass中的var键){
如果(!myClass.hasOwnProperty(key))继续;
appendChild(myClass[key]);
}
#包装器{
边框:2倍纯绿;
颜色:棕色;
}
首先
第二
第三
第四

第五个
document.getElementsByClassName方法返回一个-object,它类似于一个数组,因为它有一个应该使用的数字键

e、 g.
for(var i=0;i

使用增量数字索引后,您会注意到它实际上与myClass中的
键的行为相同,这是相当合乎逻辑的,因为
键是数字索引

发生的情况是,
HTMLCollection
以文档顺序表示元素(所谓的活动列表,反映DOM中的更改),您通过将它们附加到包装器元素来移动它们(因此,
HTMLCollection
中的顺序也会更改)

有几种技巧可以解决这个问题,最接近当前设置的技巧是从头到尾遍历
HTMLCollection
,然后
insertBefore
而不是
appendChild

for (var len = myClass.length - 1; len >=0; --len) {
    wrapper.insertBefore(myClass[len], wrapper.firstChild);
}

这是因为包装器(在您的示例中)位于您要移动到其中的元素之后,因此不会更改元素的顺序

还有另一种(更简单的)方法:。
querySelectorAll
方法返回一个(静态)
NodeList
,因此您可以放心地假设在移动节点时顺序不会改变

语法(IMHO)比
getElementsByClassname
更方便,因为它使用
CSS选择器
(很像我们将不提及的流行javascript框架)


逐步查看for循环:

1. myClass[First, Second, Third, Fourth, Fifth]; wrapper[] ; key = 0
2. myClass[Second, Third, Fourth, Fifth] ; wrapper[First]; key = 1
现在,您将获取第三个,而不是第二个,因为键是1,但您需要获取索引0处的项。这也给出了一个修正:始终在位置0处获取项目

var wrapper=document.createElement('div'),
myClass=document.getElementsByCassName('myClass');
myClass[0]。parentElement.appendChild(包装器);
wrapper.id='wrapper';
对于(var i=0;i
#包装器{
边框:2倍纯绿;
颜色:棕色;
}
首先
第二
第三
第四

第五
我为您提供了一个简单的代码工作版本。谢谢


试试看
注意:Internet Explorer 8和早期版本不支持getElementsByClassName()方法

弗斯特 第二 第三 第四 第五 函数myFunction(){ var wrapper=document.createElement('div'); var x=document.getElementsByClassName(“myClass”); 对于(变量i=0;i
通过从集合中删除项目,您正在动态更改集合(在循环本身中),这就是它的行为方式。以下是实际可行的代码:

var wrapper = document.createElement('div'),
myClass = document.getElementsByClassName('myClass'),
myClassParent = myClass[0].parentNode;

while (myClass.length) {
    wrapper.appendChild(myClass[0]);
}
myClassParent.appendChild(wrapper);
wrapper.setAttribute('id','wrapper');

。还有一个问题是集合是活动的。此外,HTMLCollections除了其成员的索引之外,还有其他可枚举属性(例如item、namedItem和length以及包含它们的元素的ID)。@RobG幸运的是,这些是继承属性,因此,
hasOwnProperty
检查避免了这个额外的问题。@Oriol-长度和元素ID不会被继承,尽管不同浏览器的可枚举性不同。另一种方法是在将元素添加到包装器之前将其添加到包装器中,以便在移动元素时将其从DOM中删除,从而也从集合中删除。@Rogier Spieker Lol!你最后一句话让我笑了!我不是那个意思,我只是不想在没有JQuery标记的情况下得到JQuery答案。但我喜欢你的回答!非常感谢。我想我将使用
文档.querySelectorAll
方法。@RobG我不太明白这样做会得到什么。@RobG的意思是,如果没有将包装器元素附加到DOM,则
getElementsByClassName
返回的集合将被清空,例如
while(myClass.length>0){wrapper.appendChild(myClass[0]);}
(这就是原因所在)
querySelectorAll
-方法更健壮,因为它在不同的条件下工作更一致(包装器可以位于DOM中的任何位置/之外)@Jessica我会尽可能晚地将包装器附加到DOM。我总是尽量减少DOM操作的次数,因为这些操作会在浏览器中触发错误。DOM中最小的更改是将元素添加到包装器,然后将包装器添加到文档,因此这将是我在这种情况下的选择。我不知道不要认为设置<代码>内文HTML>代码>作为<代码>文本内容< /代码>是一个好主意。考虑使用<代码> C克隆No/代码>。您可以为循环构造<代码>,这是更容易检查的条件。