admin管理员组文章数量:1253367
I have 5 div's
created in HTML, and I want to add all of them into a div
wrapper I created in JavaScript. I tried looping through the 5 div's
via a for-in
loop, then append the div
as a child of the wrapper
.
For some reason, the for
loop changes the 5 div's
order and doesn't append all of them in wrapper
. How can I add all div's
to wrapper
, keeping the (HTML) order, using JavaScript?
(Please don't post JQuery answers because that isn't the question. I want JavaScript answers only.)
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>
I have 5 div's
created in HTML, and I want to add all of them into a div
wrapper I created in JavaScript. I tried looping through the 5 div's
via a for-in
loop, then append the div
as a child of the wrapper
.
For some reason, the for
loop changes the 5 div's
order and doesn't append all of them in wrapper
. How can I add all div's
to wrapper
, keeping the (HTML) order, using JavaScript?
(Please don't post JQuery answers because that isn't the question. I want JavaScript answers only.)
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>
Share
Improve this question
asked Feb 7, 2016 at 23:22
JessicaJessica
9,83016 gold badges73 silver badges154 bronze badges
4
-
2
If you want order, don't iterate using
for...in
!!!. There is also the problem that the collection is live. – Oriol Commented Feb 7, 2016 at 23:59 - 1 Also, HTMLCollections have additional enumerable properties other than the indexes for their members (e.g. item, namedItem and length and the IDs of elements that have them). – RobG Commented Feb 8, 2016 at 0:23
-
@RobG Luckily these are inherited properties, so the
hasOwnProperty
check avoids this additional problem. – Oriol Commented Feb 8, 2016 at 0:29 - @Oriol— length and element IDs aren't inherited, though enumerability differs between browsers. – RobG Commented Feb 8, 2016 at 2:18
5 Answers
Reset to default 6The document.getElementsByClassName
method returns an HTMLCollection
-object, which is similar to an array, as in it has numeric keys which should be used.
e.g. for (var i = 0; i < myClass.length; ++i)
Once you use an incremental numeric index, you'll notice it actually behaves the same as your key in myClass
, which is rather logical, as the key
is the numeric index.
What is happening is that an HTMLCollection
represents elements in document order (a so called live list, which reflects the changes in the DOM) and you are moving them around by appending them to the wrapper element (hence the order within the HTMLCollection
changes too).
There are several tricks to work around this, the one closest to your current setup would be to walk through the HTMLCollection
from end to start and insertBefore
instead of appendChild
for (var len = myClass.length - 1; len >=0; --len) {
wrapper.insertBefore(myClass[len], wrapper.firstChild);
}
insertBefore
fiddle
This works because the wrapper is (in your example) after the elements you're moving into it, therefor not changing the order of the elements.
There is another (easier) approach: document.querySelectorAll
.
The querySelectorAll
method returns a (static) NodeList
, so you can safely assume the order will not change while you move nodes around.
The syntax is (IMHO) more convenient than getElementsByClassname
, as it uses CSS Selectors
(much like the popular javascript framework we won't mention)
querySelectorAll
fiddle
Look at your for loop step by step:
1. myClass[First, Second, Third, Fourth, Fifth]; wrapper[] ; key = 0
2. myClass[Second, Third, Fourth, Fifth] ; wrapper[First]; key = 1
Now instead of Second, you'll take Third, because key is 1, but you'll need to take the item at index 0. This also gives the fix: always take the item at position 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>
You are changing the collection on the fly (in the loop itself) by removing items from it, that's why it acts wired. Here's the code that should actually work:
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/byd9fer3/1/
I have a simple working version for you with code. Thanks
<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>
The simplest is to use append method from Element and use it like:
Element.prototype.append.apply(domElement, arrayOfElements);
本文标签: javascriptAdd array of elements to domStack Overflow
版权声明:本文标题:javascript - Add array of elements to dom - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1740763217a2282310.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论