Elemento móvil de JavaScript en el DOM

97

Digamos que tengo tres <div>elementos en una página. ¿Cómo puedo intercambiar posiciones del primero y del tercero <div>? jQuery está bien.

núcleo
fuente

Respuestas:

110

Trivial con jQuery

$('#div1').insertAfter('#div3');
$('#div3').insertBefore('#div2');

Si desea hacerlo repetidamente, deberá usar diferentes selectores, ya que los divs conservarán sus identificadores a medida que se muevan.

$(function() {
    setInterval( function() {
        $('div:first').insertAfter($('div').eq(2));
        $('div').eq(1).insertBefore('div:first');
    }, 3000 );
});
tvanfosson
fuente
1
@Ionut: el punto es que depende del posicionamiento relativo de los elementos. Una vez que cambia el orden, ya no puede encontrar el primero y el tercero por sus identificadores y necesita trabajar de otra manera. Mi respuesta solo pretendía ilustrar la funcionalidad de los métodos para realizar la tarea solicitada, no ser una solución integral para intercambiar el primer y tercer div en un conjunto un número arbitrario de veces.
tvanfosson
Hola chicos, una pregunta rápida: ¿Existe una manera fácil de restablecer el estado original de Dom una vez que se haya completado la función jquery anterior?
Vikita
@Vikita: sí, guarde el HTML original y luego restáurelo. Es posible que deba volver a aplicar cualquier controlador si se ha aplicado directamente en lugar de delegado a un elemento superior. Por ejemplo,var html = $('#container').html(); ...; $('#container').html(html);
tvanfosson
171

No es necesario utilizar una biblioteca para una tarea tan trivial:

var divs = document.getElementsByTagName("div");   // order: first, second, third
divs[2].parentNode.insertBefore(divs[2], divs[0]); // order: third, first, second
divs[2].parentNode.insertBefore(divs[2], divs[1]); // order: third, second, first

Esto tiene en cuenta el hecho de que getElementsByTagNamedevuelve una NodeList en vivo que se actualiza automáticamente para reflejar el orden de los elementos en el DOM a medida que se manipulan.

También puedes usar:

var divs = document.getElementsByTagName("div");   // order: first, second, third
divs[0].parentNode.appendChild(divs[0]);           // order: second, third, first
divs[1].parentNode.insertBefore(divs[0], divs[1]); // order: third, second, first

y hay varias otras permutaciones posibles, si tiene ganas de experimentar:

divs[0].parentNode.appendChild(divs[0].parentNode.replaceChild(divs[2], divs[0]));

por ejemplo :-)

NickFitz
fuente
15
Es cierto, pero es difícil discutir la elegancia y la legibilidad que ofrece algo como jQuery, sin mencionar las capacidades mejoradas listas para usar.
Crazy Joe Malloy
13
Sí, pero ¿quién solo hace esto?
tvanfosson
1
... o solo tiene 3 divs en la página
Ryan Florence
38
@todos: la pregunta original preguntaba cómo intercambiar el tercer y el primer div en una página que tenía tres div. Esa fue la pregunta que respondí. Si el OP tuviera una pregunta más compleja, deberían haberla hecho, y habrían obtenido una respuesta más compleja ;-)
NickFitz
26
Si alguien busca esto en 2014, considere esta respuesta. jQuery ERA útil en ese entonces, pero ahora ya no es tan útil, porque los navegadores están estandarizados, por lo que no es necesario agregar una biblioteca de 80 kb solo para hacer una tarea tan simple. Además, no llega a saber qué es realmente el DOM hasta que lo prueba sin jQuery :)
gustavohenke
29

.antes y después de

¡Utilice JS vanilla moderno! Mucho mejor / más limpio que antes. No es necesario hacer referencia a un padre.

const div1 = document.getElementById("div1");
const div2 = document.getElementById("div2");
const div3 = document.getElementById("div3");

div2.after(div1);
div2.before(div3);

Compatibilidad con navegadores : 94,23% global a julio de 2020

Gibolt
fuente
Aún no es compatible con Internet Explorer.
justnorris
11
No debería tener que escribir código menos fácil de mantener para ayudar a las personas en navegadores antiguos o que no se ajustan a los estándares. A menos que trabaje en una empresa, pocos usuarios se lo perderán
Gibolt
Otros métodos funcionan igual de bien con respecto a la capacidad de mantenimiento, especialmente cuando se envuelve en una función limpia agradable. Estoy a favor de escribir código moderno, pero esto es de vanguardia. Es genial saber lo que depara el futuro, pero por mucho que no me guste todo lo relacionado con IE, es importante saber cuál es el impacto de tus decisiones. En este caso, una aplicación web rota en cualquier navegador IE. Si te parece bien, ¡genial!
Agregué
1
Entonces, ¿el 27% de los usuarios son pocos usuarios ? ¡Estamos hablando de millones!
SandRock
5
En un año, ese número se acercará al 10%. Se trata principalmente de dispositivos móviles empresariales, gubernamentales y más antiguos. Esto generalmente significa dispositivos no personales o usuarios con menos inclinaciones técnicas. Las respuestas deben ser prospectivas para que no estemos estancados en el desarrollo en 2009.
Gibolt
11
jQuery.fn.swap = function(b){ 
    b = jQuery(b)[0]; 
    var a = this[0]; 
    var t = a.parentNode.insertBefore(document.createTextNode(''), a); 
    b.parentNode.insertBefore(a, b); 
    t.parentNode.insertBefore(b, t); 
    t.parentNode.removeChild(t); 
    return this; 
};

y utilícelo así:

$('#div1').swap('#div2');

si no desea utilizar jQuery, podría adaptar fácilmente la función.

Darin Dimitrov
fuente
5
var swap = function () {
    var divs = document.getElementsByTagName('div');
    var div1 = divs[0];
    var div2 = divs[1];
    var div3 = divs[2];

    div3.parentNode.insertBefore(div1, div3);
    div1.parentNode.insertBefore(div3, div2);
};

Esta función puede parecer extraña, pero depende en gran medida de los estándares para funcionar correctamente. De hecho, puede parecer que funciona mejor que la versión de jQuery que publicó tvanfosson, que parece hacer el intercambio solo dos veces.

¿En qué peculiaridades de los estándares se basa?

insertBefore Inserta el nodo newChild antes del nodo secundario existente refChild. Si refChild es nulo, inserte newChild al final de la lista de hijos. Si newChild es un objeto DocumentFragment, todos sus elementos secundarios se insertan, en el mismo orden, antes de refChild. Si newChild ya está en el árbol, primero se quita.

Ionuț G. Stan
fuente
0

El enfoque de Jquery mencionado en la parte superior funcionará. También puede usar JQuery y CSS. Diga, por ejemplo, que en Div one ha aplicado class1 y div2 ha aplicado clase class2 (por ejemplo, cada clase de CSS proporciona una posición específica en el navegador), ahora puede intercambiar las clases, use jquery o javascript (que cambiará la posición)

Rajat
fuente
0

Perdón por tropezar con este hilo. Tropecé con el problema de "intercambiar elementos DOM" y jugué un poco.

El resultado es una "solución" nativa de jQuery que parece ser realmente bonita (desafortunadamente no sé qué está sucediendo en las partes internas de jQuery al hacer esto)

El código:

$('#element1').insertAfter($('#element2'));

La documentación de jQuery dice que insertAfter() mueve el elemento y no lo clona

storrm
fuente