Javascript - Moving a Div that is Uniquely Identified by its Parent

51 Views Asked by At

Need to move a div that does not have any unique identifiers in front of another div that does not have any unique identifiers. However, the children divs do have unique identifiers.

Starting:

<div class="container1">
  <div class="generic">
    <div id="child1"></div>
  </div>
  <div class="generic">
    <div id="child2"></div>
  </div>
  <div class="generic">
    <div id="child4"></div>
  </div>
</div>
<div class="container2">
  <div class="generic">
    <div id="child3"></div>
  </div>
</div>

I'd like to move the parent of the child3 div after the parent of the child2 div. The result should look like:

<div class="container1">
  <div class="generic">
    <div id="child1"></div>
  </div>
  <div class="generic">
    <div id="child2"></div>
  </div>
  <div class="generic">
    <div id="child3"></div>
  </div>
  <div class="generic">
    <div id="child4"></div>
  </div>
</div>
<div class="container2">
</div>

Any ideas?

I've looked into jQuery prependTo() and appendTo(), in combination with parent(), but I can't get seem to get them to work properly.

Edited for more context. In my original posting, swap would have worked, but the divs are in different containers, and I'd like to move the parent div of child3 without swapping it with another div.

2

There are 2 best solutions below

2
On

from your child, you take parentnode, and you swap the nodes.

const node1 = document.querySelector('#child3').parentNode;
const node2 = document.querySelector('#child4').parentNode;

swapNodes(node1, node2);

function swapNodes(n1, n2) {

  const p1 = n1.parentNode;
  const p2 = n2.parentNode;
  let i1, i2;

  if (!p1 || !p2 || p1.isEqualNode(n2) || p2.isEqualNode(n1)) return;

  for (let i = 0; i < p1.children.length; i++) {
    if (p1.children[i].isEqualNode(n1)) {
      i1 = i;
    }
  }
  for (let i = 0; i < p2.children.length; i++) {
    if (p2.children[i].isEqualNode(n2)) {
      i2 = i;
    }
  }

  if (p1.isEqualNode(p2) && i1 < i2) {
    i2++;
  }
  p1.insertBefore(n2, p1.children[i1]);
  p2.insertBefore(n1, p2.children[i2]);
}
<div class="generic">
  <div id="child1">child 1</div>
</div>
<div class="generic">
  <div id="child2">child 2</div>
</div>
<div class="generic">
  <div id="child4">child 4</div>
</div>
<div class="generic">
  <div id="child3">child 3</div>
</div>

0
On

new snippet regarding changes you made in your exemple.

const idToMove = 'child3';
const idToWhere = 'child2';

moveNode(idToMove, idToWhere);

function moveNode(idToMove, idToWhere) {
  const nodeToDelete = document.querySelector('#' + idToMove).parentNode; //div parent class generic where reside idToMove
  const nodeToMove = nodeToDelete; // we have to avoid 2 div with same id
  nodeToMove.querySelector('div').id = 'tmp'; // changing id of node to move
  nodeToDelete.remove(); // delete original node
  nodeToMove.querySelector('div').id = idToMove; // put back the right id in the node to mode

  const nodeWhere = document.querySelector('#' + idToWhere).parentNode;
  nodeWhere.insertAdjacentElement('afterend', nodeToMove); // inserting after
}
<div class="container1">
  <div class="generic">
    <div id="child1">child1</div>
  </div>
  <div class="generic">
    <div id="child2">child2</div>
  </div>
  <div class="generic">
    <div id="child4">child4</div>
  </div>
</div>
<div class="container2">
  <div class="generic">
    <div id="child3">child3</div>
  </div>
</div>

That's really following structure you gave in exemple: moving the node inside (1 level) div parent.

It's using insertAdjacentElement, you can check here : https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentElement