Oto-obong Eshiett
Oto-obong Eshiett

Reputation: 1679

How can I properly take the children of a parent element and append it as the children of another

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

Answers (3)

user11657407
user11657407

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

Kaiido
Kaiido

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

Ramesh Reddy
Ramesh Reddy

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

Related Questions