Reputation: 1679
I have a small test app where I am trying to get the children elements of a parent element and append them as children to another element. I have written a code to do that, but it turns out not to be perfect.
function run() {
var elems = document.getElementById('happy').children;
for (i = 0; i < elems.length; i++) {
document.getElementById('enabled').appendChild(elems[i])
}
}
body {
padding: 30px 30px 30px 30px;
}
<h2>The Button Element</h2>
<div id="happy">
<span>Hello!</span>
<span>Sad!</span>
<span>Click me!</span>
<span>Try me!</span>
</div>
<div id="enabled">
<button type="button" onclick="run()">Click me!</button>
</div>
When the 'Click me!' button is clicked, out of 'Hello!', 'Sad!', 'Click me!', 'Try me!' only 'Hello!' and 'Click me!' move. To make the others move the 'Click me!' button must be hit multiple times.
I want all of them to move at first click, how do I solve this issue?
Upvotes: 0
Views: 62
Reputation: 312
A loop counter would not work as the elems
array is getting smaller for each iteration of the loop. This would always only append half of the child elements.
function run() {
var elems = document.getElementById('happy').children;
while (elems.length > 0) {
document.getElementById('enabled').appendChild(elems[0])
}
}
<!DOCTYPE html>
<html>
<body style="padding: 30px 30px 30px 30px;">
<h2>The Button Element</h2>
<div id="happy">
<span>Hello</span>
<span>Sad</span>
<span>Click Me!</span>
<span>try Me!</span>
</div>
<div id="enabled">
<button type="button" onclick="run()">Click Me!</button>
</div>
</body>
</html>
Upvotes: 1
Reputation: 136716
You can use the Range API, to select the content of your first node, then extract it to a DocumentFragment. Finally you just have to append this fragment to your target element:
document.getElementById('btn').addEventListener('click', function() {
const source = document.getElementById('happy');
const target = document.getElementById('enabled');
const range = document.createRange();
range.selectNodeContents(source);
const content = range.extractContents();
target.append(content);
}, {once: true});
#happy { color: green; border: 1px solid }
#enabled { color: red; border: 1px solid }
<h2>The Button Element</h2>
<div id="happy">
<span>Hello</span>
<span>Sad</span>
<span>Click Me!</span>
<span>try Me!</span>
</div>
<div id="enabled">
<button type="button" id="btn">Click Me!</button>
</div>
Upvotes: 1
Reputation: 10662
If you don't want to use loops you can do something like this:
function run() {
var enabledDiv = document.getElementById('enabled');
var happyDiv = document.getElementById('happy');
enabledDiv.innerHTML += happyDiv.innerHTML;
happyDiv.innerHTML = "";
}
<!DOCTYPE html>
<html>
<body style="padding: 30px 30px 30px 30px;">
<h2>The Button Element</h2>
<div id="happy">
<span>Hello</span>
<span>Sad</span>
<span>Click Me!</span>
<span>try Me!</span>
</div>
<div id="enabled">
<button type="button" onclick="run()">Click Me!</button>
</div>
</body>
</html>
Upvotes: 1