添加元素数组到dom

时间:2016-02-07 23:22:37

标签: javascript

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

出于某种原因,for循环更改了5 div's订单,并且不会将所有订单都附加在wrapper中。如何使用JavaScript将所有div's添加到wrapper,保留(HTML)顺序?

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

JSFiddle

var wrapper = document.createElement('div'),
  myClass = document.getElementsByClassName('myClass');

myClass[0].parentElement.appendChild(wrapper);
wrapper.id = 'wrapper';

for (var key in myClass) {
  if (!myClass.hasOwnProperty(key)) continue;

  wrapper.appendChild(myClass[key]);
}
#wrapper {
  border: 2px solid green;
  color: brown;
}
<div class="myClass">First</div>
<div class="myClass">Second</div>
<div class="myClass">Third</div>
<div class="myClass">Fourth</div>
<div class="myClass">Fifth</div>

4 个答案:

答案 0 :(得分:3)

document.getElementsByClassName方法返回一个HTMLCollection - 对象,它类似于数组,因为它具有应该使用的数字键。

e.g。 for (var i = 0; i < myClass.length; ++i)

使用增量数字索引后,您会发现它实际上与key in myClass的行为相同,这是合乎逻辑的,因为key 数字索引。

正在发生的事情是,HTMLCollection代表文档顺序中的元素 (所谓的实时列表,它反映了DOM中的更改)并且您通过将它们附加到包装元素来移动它们(因此HTMLCollection内的顺序也会发生变化)。

有几个技巧可以解决这个问题,最接近当前设置的一个技巧是从结尾开始HTMLCollection而不是insertBefore而不是appendChild

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

insertBefore fiddle

这是有效的,因为包装器(在你的例子中)是之后你要移入的元素,因此不会改变元素的顺序。

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

语法(IMHO)比getElementsByClassname更方便,因为它使用CSS Selectors(很像我们不会提到的流行的javascript框架)

querySelectorAll fiddle

答案 1 :(得分:3)

逐步查看你的for循环:

1. myClass[First, Second, Third, Fourth, Fifth]; wrapper[] ; key = 0
2. myClass[Second, Third, Fourth, Fifth] ; wrapper[First]; key = 1

现在取代Second,你将取第三个,因为key为1,但你需要在索引0处取项。这也给出了修正:总是把项目放在0位。

var wrapper = document.createElement('div'),
  myClass = document.getElementsByClassName('myClass');

myClass[0].parentElement.appendChild(wrapper);
wrapper.id = 'wrapper';

for (var i = 0; i < myClass.length; i++) {
  wrapper.appendChild(myClass[0]);
}
#wrapper {
  border: 2px solid green;
  color: brown;
}
<div class="myClass">First</div>
<div class="myClass">Second</div>
<div class="myClass">Third</div>
<div class="myClass">Fourth</div>
<div class="myClass">Fifth</div>

答案 2 :(得分:1)

您正在通过从中删除项目来动态更改集合(在循环中),这就是它有效连接的原因。这是应该实际工作的代码:

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');

https://jsfiddle.net/byd9fer3/1/

答案 3 :(得分:0)

我有一个简单的工作版本代码。感谢

<html>
<body>

<button onclick="myFunction()">Try it</button>

<p><strong>Note:</strong> The getElementsByClassName() method is not supported in Internet Explorer 8 and earlier versions.</p>

<div class="myClass">First</div>
<div class="myClass">Second</div>
<div class="myClass">Third</div>
<div class="myClass">Fourth</div>
<div class="myClass">Fifth</div>

<script>
function myFunction() {

    var wrapper = document.createElement('div');
    var x = document.getElementsByClassName("myClass");
    

for(var i=0; i < x.length;++i){
    var newdiv = document.createElement('div');
    newdiv.appendChild(document.createTextNode(x[i].innerHTML));
    wrapper.appendChild(newdiv);
   }

 document.body.appendChild(wrapper);
}
</script>

</body>
</html>