Cómo intercambiar nodos hijos DOM en JavaScript?


¿Cuál es la forma más fácil de intercambiar el orden de los nodos hijos?

Por ejemplo, quiero que childNode[3] sea childNode[4] y viceversa.

Author: Myforwik, 2012-03-16

6 answers

No hay necesidad de clonar. Puedes mover un nodo antes que el otro con esto:

childNode[4].parentNode.insertBefore(childNode[4], childNode[3]);

Se obtiene el padre del nodo. Luego llamas al método insertBefore en el padre y le pasas el nodo childNode[4] y le dices que quieres insertarlo antes de childNode [3]. Eso le dará el resultado de intercambiar su orden por lo que 4 será antes de 3 cuando se hace.

Referencia documentación sobre insertBefore.

Cualquier nodo que se inserta en el DOM que ya está en el DOM primero se elimina automáticamente y luego se inserta de nuevo por lo que no hay necesidad de eliminarlo manualmente primero.

 50
Author: jfriend00,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-16 06:21:23

La respuesta de jfriend00 realmente no intercambia elementos ("intercambia" solo elementos que están uno al lado del otro y solo bajo el mismo nodo padre). Esto está bien, ya que esta era la pregunta.

Este ejemplo intercambia elementos clonándolo pero independientemente de su posición y nivel DOM:

// Note: Cloned copy of element1 will be returned to get a new reference back
function exchangeElements(element1, element2)
{
    var clonedElement1 = element1.cloneNode(true);
    var clonedElement2 = element2.cloneNode(true);

    element2.parentNode.replaceChild(clonedElement1, element2);
    element1.parentNode.replaceChild(clonedElement2, element1);

    return clonedElement1;
}

Editar: Añadido retorno de nueva referencia (si desea mantener la referencia, por ejemplo, para acceder al atributo "parentNode" (de lo contrario se pierde)). Ejemplo: e1 = exchangeElements(e1, e2);

 8
Author: StanE,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-03 21:09:26

Use .before o .after!

Esto es vainilla JS!

childNode[3].before(childNode[4]);

O

childNode[4].after(childNode[3]);

Para más intercambio de durabilidad, intente:

function swap(node1, node2) {
    const afterNode2 = node2.nextElementSibling;
    const parent = node2.parentNode;
    node1.replaceWith(node2);
    parent.insertBefore(node1, afterNode2);
}

Esto debería funcionar, incluso si los padres no coinciden

 2
Author: Gibolt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-20 22:24:56

Para un intercambio real de cualquier nodo sin cloneNode:

    <div id="d1">D1</div>
    <div id="d2">D2</div>
    <div id="d3">D3</div>

Con la función SwapNode (usando PrototypeJS):

function SwapNode(N1, N2)  {
N1 = $(N1);
N2 = $(N2);

if (N1 && N2) {
    var P1 = N1.parentNode;
    var T1 = document.createElement("span");    
    P1.insertBefore(T1, N1);

    var P2 = N2.parentNode;
    var T2 = document.createElement("span");
    P2.insertBefore(T2, N2);

    P1.insertBefore(N2, T1);
    P2.insertBefore(N1, T2);

    P1.removeChild(T1);
    P2.removeChild(T2);
}
}
SwapNode('d1', 'd2');
SwapNode('d2', 'd3');

Producirá:

<div id="d3">D3</div>
<div id="d1">D1</div>
<div id="d2">D2</div>
 1
Author: Buck,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-16 21:02:17

Prueba este método:

  1. Get the parent element
  2. Almacenar el two elements you want to swap
  3. Almacenar el .nextSibling of the node that is last in order eg: [1,2,3,4] = > queremos intercambiar 3 & 2 luego almacenar nextSibling de 3, '4'.

  4. .insertBefore(3,2);

  5. .insertBefore (2,siguiente);
 0
Author: Chad Mx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-09 22:51:02

Necesitaba una función para intercambiar dos nodos arbitrarios manteniendo los elementos intercambiados en el mismo lugar en el dom. Por ejemplo, si a estaba en la posición 2 relativa a su padre y b estaba en la posición 0 relativa a su padre, b debería reemplazar la posición 2 de a y a debería reemplazar al hijo 0 de b.

Esta es mi solución que permite que el intercambio esté en partes completamente diferentes del dom. Tenga en cuenta que la el intercambio no puede ser un simple intercambio de tres pasos. Cada uno de los dos elementos debe ser eliminado del dom primero porque pueden tener hermanos que necesitarían actualización, etc.

Solución: Puse dos div de soporte para mantener el lugar de cada nodo para mantener el orden relativo del hermano. Luego reinserto cada uno de los nodos en el marcador de posición del otro, manteniendo la posición relativa que el nodo intercambiado tenía antes del intercambio. (Mi solución es similar a la de Buck).

Función swapDom (a, b) {

 var aParent = a.parentNode;
 var bParent = b.parentNode;

 var aHolder = document.createElement("div");
 var bHolder = document.createElement("div");

 aParent.replaceChild(aHolder,a);
 bParent.replaceChild(bHolder,b);

 aParent.replaceChild(b,aHolder);
 bParent.replaceChild(a,bHolder);

}

 0
Author: Jack Briner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-01 00:27:06