1
 function rearrange(x, y) {
    x.parentNode.replaceChild(x, y);
    x.parentNode.insertBefore(y,x); 
 }

If I do

var a = document.getElementsByClassName('btn-button-google')[0];
var b = document.getElementsByClassName('btn-button-doodle')[0];
rearrange(b,a);

I get the following error

NotFoundError: Failed to execute 'replaceChild' on 'Node': The node to be replaced is not a child of this node.

Which I understand since a is in one html div and b is in another div, but I'm curious as how to fix this from happening. this works

rearrange(b.parentNode,a.parentNode);

Since they are in the same node.

Example HTML

<div class="container">
   <div class="group">
     <a href="" class="btn-button-bold"><a>
     <a href="" class="btn-button-italic"><a>
     <a href="" class="btn-button-strike"><a>
   </div>
   <div class="group">
     <a href="" class="btn-button-font"><a>
     <a href="" class="btn-button-ffamily"><a>
     <a href="" class="btn-button-google"><a>
   </div>
   <div class="group">
      <a href="" class="btn-button-smilies"><a>
     <a href="" class="btn-button-doodle"><a>
     <a href="" class="btn-button-source"><a>
   </div>
</div>
Manuel Allenspach
  • 12,467
  • 14
  • 54
  • 76
EasyBB
  • 6,176
  • 9
  • 47
  • 77
  • `x.parentNode.replaceChild(y, x);` [MDN `replaceChild`](https://developer.mozilla.org/en-US/docs/Web/API/Node.replaceChild) – cookie monster Jul 16 '14 at 17:27
  • Alrighty I'll give it a whirl – EasyBB Jul 16 '14 at 17:28
  • However, if `x` needs to go in the place of `y`, you'll need to first grab `y`'s parent and next sibling before moving it so that you'll have a point of reference to place `x`. – cookie monster Jul 16 '14 at 17:29
  • 1
    ...also, I don't see a `btn-button-doodle` in your HTML. – cookie monster Jul 16 '14 at 17:31
  • yeah it was just a fake mock of the html to get atleast the idea of what I meant on the parent nodes and so forth. – EasyBB Jul 16 '14 at 17:31
  • Did you mean like so ? `var newPos = y.parentNode.nextSibling;` and then `x.parentNode.insertBefore(newPos,x);` ? – EasyBB Jul 16 '14 at 17:32
  • 1
    It would be `var yPar = y.parentNode, ySib = y.nextSibling; x.parentNode.replaceChild(y, x); yPar.insertBefore(x, ySib);` When we moved `y`, we lost track of its original position. So we reference it before the move. – cookie monster Jul 16 '14 at 17:34
  • Very good can you post as an answer so I can +1 and accept the answer – EasyBB Jul 16 '14 at 17:35

1 Answers1

2

The .replaceChild method accepts the replacement as the first argument and the child to be replaced as the second. You have them reversed, which is causing the error.

Furthermore, if the intent is to swap, you'll need to hold a reference to the original position of y, since once you move it, it'll be forgotten.

This will work for most cases:

var yPar = y.parentNode, ySib = y.nextSibling; 
x.parentNode.replaceChild(y, x); 
yPar.insertBefore(x, ySib);

Keep in mind, that there's an additional issue to consider. It won't be an issue as long as the two nodes have different parents, but if the share a parent, and are adjacent to each other, and the cached nextSibling is the same as x, then it'll have no effect. So you'll need to test for this if that may be a possibility, and handle that special case.

cookie monster
  • 10,671
  • 4
  • 31
  • 45