¿Cómo mover un elemento a otro elemento?


1689

Me gustaría mover un elemento DIV dentro de otro. Por ejemplo, quiero mover esto (incluidos todos los niños):

<div id="source">
...
</div>

dentro de esto:

<div id="destination">
...
</div>

para que tenga esto:

<div id="destination">
  <div id="source">
    ...
  </div>
</div>

21
Simplemente use $ (target_element) .append (to_be_inserted_element);
Mohammad Areeb Siddiqui 27/0613

2
O bien: destination.appendChild (fuente) usando JavaScript simple
luke

¿podemos lograr esto usando CSS? es eso posible ?
RajKumar Samala

66
@RajKumarSamala CSS no puede alterar la estructura del HTML, solo su presentación.
Mark Richman

Respuestas:


39

¿Alguna vez has probado JavaScript simple ... destination.appendChild(source);?

onclick = function(){ destination.appendChild(source); }
div{ margin: .1em; } 
#destination{ border: solid 1px red; }
#source {border: solid 1px gray; }
<!DOCTYPE html>
<html>

 <body>

  <div id="destination">
   ###
  </div>
  <div id="source">
   ***
  </div>

 </body>
</html>


* alguien prefijo el evento global onclick del fragmento de demostración con la palabra clave varen su intento de mejorar la publicación, ¡pero está mal!
Bekim Bacaj

66
Es sorprendente cómo la gente todavía piensa que jQuery es igual a JavaScript. Ya no es necesario usar jQuery en 2017.
nkkollaw

2
no es necesario usar jquery en 2017, pero a veces ayuda usar algo más liviano y similar para las tareas que te encuentras haciendo una y otra vez en cada proyecto. Utilizo cash-dom como una manera fácil de escuchar eventos document.ready, window.load de una manera amigable para todos los navegadores. pan comido.
eballeste

1
Cambiando esto a la respuesta aceptada, ahora que es 2020 :)
Mark Richman

1
Es sorprendente cómo la gente todavía piensa que jQuery es igual a JavaScript. Ya no hay necesidad de jQuery en 2020, de verdad.
ii iml0sto1

1794

Es posible que desee utilizar la appendTofunción (que se agrega al final del elemento):

$("#source").appendTo("#destination");

Alternativamente, podría usar la prependTofunción (que se agrega al comienzo del elemento):

$("#source").prependTo("#destination");

Ejemplo:


23
Una advertencia de que esto puede no funcionar correctamente en jQuery mobile, ya que puede crear otra copia del elemento.
Jordan Reiter

32
¿el appenTo crea una copia o mueve todo el div al destino? (porque si se copia, crearía errores al llamar al div por la identificación)

50
Aquí hay un excelente artículo sobre Eliminar, reemplazar y mover elementos en jQuery: elated.com/articles/jquery-removing-replacing-moving-elements
xhh

42
Tenga en cuenta que la documentación de jQuery para appendTo indica que el elemento se mueve: it will be moved into the target (not cloned) and a new set consisting of the inserted element is returned- api.jquery.com/appendto
John K

15
No lo estás moviendo, solo agregando. La siguiente respuesta hace un MOVIMIENTO apropiado.
Aaron

913

mi solución:

MOVERSE:

jQuery("#NodesToMove").detach().appendTo('#DestinationContainerNode')

COPIAR:

jQuery("#NodesToMove").appendTo('#DestinationContainerNode')

Tenga en cuenta el uso de .detach (). Al copiar, tenga cuidado de no duplicar ID.


86
La mejor respuesta. La respuesta aceptada crea una copia, no mueve el elemento como pide la pregunta.
paulscode

97
Lo sentimos, pero la respuesta aceptada de Andrew Hare es correcta: la separación es innecesaria. Pruébelo en el JSFiddle de Pixic anterior: si elimina las llamadas de desconexión, funciona exactamente igual, es decir, hace un movimiento, NO una copia. Aquí está la bifurcación con solo ese cambio: jsfiddle.net/D46y5 Como se documenta en la API: api.jquery.com/appendTo : "Si un elemento seleccionado de esta manera se inserta en una sola ubicación en otra parte del DOM, se moverá en el objetivo (no clonado) y se devuelve un nuevo conjunto que consiste en el elemento insertado "
John - No es un número

8
@ John-NotANumber tiene razón: no se necesita detach () aquí. La respuesta aceptada es la mejor, solo necesita leer la documentación correctamente.
LeonardChallis

11
La documentación de appendTo también dice: "Si hay más de un elemento de destino, sin embargo, se crearán copias clonadas del elemento insertado para cada destino después del primero, y se devolverá ese nuevo conjunto (el elemento original más los clones)". Entonces, en el caso general, ¡esta solución también PUEDE crear copias!
Vincent Pazeller

¡estupendo! O puede usar esto para ser más específico sobre dónde moverse$('#nodeToMove').insertAfter('#insertAfterThisElement');
Victor Augusto el

108

Acabo de usar:

$('#source').prependTo('#destination');

Lo que agarré de aquí .


77
Bueno, la desconexión es útil cuando desea retener el elemento y volver a insertarlo más tarde, pero en su ejemplo lo reinsertará instantáneamente de todos modos.
Tim Büthe

1
Me temo que no estoy asimilando lo que estás diciendo, ¿podrías proporcionar un código de muestra?
kjc26ster

1
Quiero decir, prependTo, separa el elemento de su posición original y lo inserta en el nuevo. Por otro lado, la función de desconexión simplemente separa el elemento seleccionado y puede guardarlo en una variable para insertarlo en el DOM en un momento posterior. La cuestión es que su llamada de desconexión es innecesaria. Elimínalo y lograrás el mismo efecto.
Tim Büthe el

1
Increíble que las modificaciones cambiaron esta respuesta por completo hasta el punto de que otra respuesta se añadió un año más tarde (idéntica a la original) y consiguieron más de 800 upvotes ...
hlscalon

96

¿Qué pasa con una solución de JavaScript ?

// Declare a fragment:
var fragment = document.createDocumentFragment();

// Append desired element to the fragment:
fragment.appendChild(document.getElementById('source'));

// Append fragment to desired element:
document.getElementById('destination').appendChild(fragment);

Echale un vistazo.


8
¿Por qué usar createDocumentFragment en lugar de simplemente document.getElementById ('destino'). AppendChild (document.getElementById ('fuente'))?
Gunar Gessner

66
@ GunarC.Gessner, suponiendo que necesite modificar el objeto fuente antes de agregarlo al objeto de destino, entonces el mejor enfoque es usar el fragmento que es un objeto imaginario y no es parte del árbol DOM, obtiene un mejor rendimiento al modificar el objeto de origen cuando se ha hecho la transición desde su lugar original (ahora está dentro del fragmento) en lugar de modificarlo en su lugar inicial antes de agregarlo.
Ali Bassam

55
Quiero agregar por la relevancia de ofrecer una solución pura de JavaScript. No se debe suponer que jQuery siempre se usa
Alexander Fradiani

1
Pregunta: Al agregar el nodo hijo, ¿estamos perdiendo los eventos adjuntos?
jimasun

1
La respuesta a mi propia pregunta es sí, mantiene los eventos adjuntos.
jimasun

95

Si el lugar divdonde desea colocar su elemento tiene contenido dentro y desea que el elemento se muestre después del contenido principal:

  $("#destination").append($("#source"));

Si el lugar divdonde desea colocar su elemento tiene contenido adentro y desea mostrar el elemento antes del contenido principal:

$("#destination").prepend($("#source"));

Si el lugar divdonde desea colocar su elemento está vacío, o si desea reemplazarlo por completo:

$("#element").html('<div id="source">...</div>');

Si desea duplicar un elemento antes de cualquiera de los anteriores:

$("#destination").append($("#source").clone());
// etc.

Me parece un poco difícil leer todas las letras en negrita, pero esta es la respuesta más informativa, por lo que recibe mi voto positivo.
Michael Scheper

32

Puedes usar:

Para insertar después,

jQuery("#source").insertAfter("#destination");

Para insertar dentro de otro elemento,

jQuery("#source").appendTo("#destination");

20

Si desea una demostración rápida y más detalles sobre cómo mover elementos, pruebe este enlace:

http://html-tuts.com/move-div-in-another-div-with-jquery


Aquí hay un breve ejemplo:

Para mover ARRIBA un elemento:

$('.whatToMove').insertBefore('.whereToMove');

Para moverse DESPUÉS de un elemento:

$('.whatToMove').insertAfter('.whereToMove');

Para moverse dentro de un elemento, ARRIBA TODOS los elementos dentro de ese contenedor:

$('.whatToMove').prependTo('.whereToMove');

Para moverse dentro de un elemento, DESPUÉS DE TODOS los elementos dentro de ese contenedor:

$('.whatToMove').appendTo('.whereToMove');

19

Puede usar el siguiente código para mover el origen al destino

 jQuery("#source")
       .detach()
       .appendTo('#destination');

intente trabajar codepen


11

Antigua pregunta, pero llegó aquí porque necesito mover el contenido de un contenedor a otro, incluidos todos los oyentes de eventos .

jQuery no tiene una forma de hacerlo, pero la función DOM estándar appendChild sí.

//assuming only one .source and one .target
$('.source').on('click',function(){console.log('I am clicked');});
$('.target')[0].appendChild($('.source')[0]);

El uso de appendChild elimina el .source y lo coloca en el destino, incluidos sus oyentes de eventos: https://developer.mozilla.org/en-US/docs/Web/API/Node.appendChild


6

También puedes probar:

$("#destination").html($("#source"))

Pero esto sobrescribirá completamente todo lo que tenga #destination.


2
Y rompa los oyentes de eventos en el elemento movido.
Igor Pomaranskiy

4

Noté una gran pérdida de memoria y una diferencia de rendimiento entre insertAfter& aftero insertBefore& before.. Si tiene toneladas de elementos DOM, o necesita usar after()o before()dentro de un evento MouseMove , la memoria del navegador probablemente aumentará y las próximas operaciones se ejecutarán muy lentamente.

La solución que acabo de experimentar es usar inserBefore en su lugar before()e insertAfter en su lugar after().


Esto suena como un problema dependiente de la implementación del motor JavaScript. ¿Con qué versión de navegador y motor JS ves esto?
Mark Richman

1
Estoy en la versión 36.0.1985.125 de Chrome y estoy usando jQuery v1.11.1. Ato una función en el evento mousemove, que mueve un DIV simple hacia arriba o hacia abajo sobre el elemento sobre el que está el mouse. Por lo tanto, este evento y función se ejecuta mientras arrastra el cursor. La pérdida de memoria ocurre con after () y before (), si mueve el cursor durante 30 segundos +, y desaparece si solo uso insertAfter & insertBefore en su lugar.
spetsnaz

1
Abriría un error con Google en eso.
Mark Richman

2

Puedes usar JavaScript puro, usando el appendChild()método ...

El método appendChild () agrega un nodo como el último hijo de un nodo.

Consejo: Si desea crear un nuevo párrafo, con texto, recuerde crear el texto como un nodo de texto que agregue al párrafo, luego agregue el párrafo al documento.

También puede usar este método para mover un elemento de un elemento a otro.

Consejo: Utilice el método insertBefore () para insertar un nuevo nodo secundario antes de un nodo secundario específico existente.

Entonces puede hacer eso para hacer el trabajo, esto es lo que creé para usted, usar appendChild(), ejecutar y ver cómo funciona para su caso:

function appendIt() {
  var source = document.getElementById("source");
  document.getElementById("destination").appendChild(source);
}
#source {
  color: white;
  background: green;
  padding: 4px 8px;
}

#destination {
  color: white;
  background: red;
  padding: 4px 8px;
}

button {
  margin-top: 20px;
}
<div id="source">
  <p>Source</p>
</div>

<div id="destination">
  <p>Destination</p>
</div>

<button onclick="appendIt()">Move Element</button>


0

En aras de la exhaustividad, hay otro enfoque wrap()o wrapAll()mencionado en este artículo . Por lo tanto, la pregunta del OP podría resolverse de esta manera (es decir, suponiendo <div id="destination" />que aún no exista, el siguiente enfoque creará un contenedor de este tipo desde cero: el OP no tenía claro si el contenedor ya existe o no):

$("#source").wrap('<div id="destination" />')
// or
$(".source").wrapAll('<div id="destination" />')

Suena prometedor Sin embargo, cuando intentaba hacer $("[id^=row]").wrapAll("<fieldset></fieldset>")en múltiples estructuras anidadas como esta:

<div id="row1">
    <label>Name</label>
    <input ...>
</div>

Los envuelve correctamente <div>...</div>y <input>...</input>PERO ALGUNA DEJA EL <label>...</label>. Así que terminé usando el explícito en su $("row1").append("#a_predefined_fieldset")lugar. Entonces, YMMV.


Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.