Come spostare un elemento in un altro elemento?


1689

Vorrei spostare un elemento DIV all'interno di un altro. Ad esempio, voglio spostare questo (inclusi tutti i bambini):

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

in questo:

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

così ho questo:

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

21
Basta usare $ (target_element) .append (to_be_inserted_element);
Mohammad Areeb Siddiqui,

2
Oppure: destination.appendChild (fonte) usando javascript semplice
luke,

possiamo ottenere questo tramite CSS? è possibile ?
RajKumar Samala,

6
@RajKumarSamala I CSS non possono alterare la struttura dell'HTML, ma solo la sua presentazione.
Mark Richman,

Risposte:


39

Hai mai provato il semplice JavaScript ... 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>


* qualcuno ha preceduto l' evento globale onclick dello snippet demo con la parola chiave varnel suo tentativo di migliorare il post - ma è sbagliato!
Bekim Bacaj,

6
È incredibile come la gente pensi ancora che jQuery sia uguale a JavaScript. Non c'è più bisogno di jQuery nel 2017, davvero.
nkkollaw,

2
non c'è bisogno di jquery nel 2017, ma a volte aiuta a usare qualcosa di più leggero e simile per le attività che ti ritrovi a svolgere più volte in ogni singolo progetto. io uso cash-dom come un modo semplice per ascoltare document.ready, window.load eventi in un modo cross-browser amichevole. vai tranquillo.
eballeste,

1
Cambiando questo alla risposta accettata, ora che è il 2020 :)
Mark Richman,

1
È incredibile come la gente pensi ancora che jQuery sia uguale a JavaScript. Non c'è più bisogno di jQuery nel 2020, davvero.
ii iml0sto1

1794

Potresti voler usare la appendTofunzione (che si aggiunge alla fine dell'elemento):

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

In alternativa puoi usare la prependTofunzione (che aggiunge all'inizio dell'elemento):

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

Esempio:


23
Un avviso che potrebbe non funzionare correttamente in jQuery mobile, in quanto potrebbe invece creare un'altra copia dell'elemento.
Jordan Reiter,

32
l'app crea una copia o sposta effettivamente l'intero div nella destinazione? (perché se copia, creerebbe errori quando si chiama il div

50
Ecco un eccellente articolo su Rimozione, sostituzione e spostamento di elementi in jQuery: elated.com/articles/jquery-removing-replacing-moving-elements
xhh,

42
Nota la documentazione di jQuery per appendTo afferma che l'elemento viene spostato: 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
Non lo stai spostando, stai solo aggiungendo. Di seguito la risposta fa un SPOSTAMENTO corretto.
Aaron,

913

la mia soluzione:

MOSSA:

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

COPIA:

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

Nota l'uso di .detach (). Durante la copia, fare attenzione a non duplicare gli ID.


86
Migliore risposta. La risposta accettata crea una copia, non sposta l'elemento come fa la domanda.
paulscode

97
Siamo spiacenti, ma la risposta accettata da Andrew Hare è corretta: il distacco non è necessario. Provalo nel JSFiddle di Pixic sopra - se rimuovi le chiamate di distacco funziona esattamente lo stesso, cioè fa una mossa, NON una copia. Ecco il fork con un solo cambiamento: jsfiddle.net/D46y5 Come documentato nell'API: api.jquery.com/appendTo : "Se un elemento selezionato in questo modo viene inserito in una singola posizione altrove nel DOM, verrà spostato nel target (non clonato) e viene restituito un nuovo set costituito dall'elemento inserito "
John - Not A Number

8
@ John-NotANumber ha ragione: qui non è necessario detach (). La risposta accettata È la migliore, devi solo leggere correttamente la documentazione.
LeonardChallis,

11
La documentazione appendTo dice anche: "Se esiste più di un elemento target, tuttavia, le copie clonate dell'elemento inserito verranno create per ogni target dopo il primo e verrà restituito quel nuovo set (l'elemento originale più i cloni)". Quindi, nel caso generale, questa soluzione PU also anche creare copie!
Vincent Pazeller,

grande! Oppure puoi usare questo per essere più specifici su dove spostarti$('#nodeToMove').insertAfter('#insertAfterThisElement');
Victor Augusto,

108

Ho appena usato:

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

Che ho preso da qui .


7
Bene, staccare è utile quando vuoi aggrapparti all'elemento e reinserirlo in seguito, ma nel tuo esempio lo reinserisci immediatamente comunque.
Tim Büthe

1
Temo di non aver capito bene cosa stai ottenendo, potresti fornire un codice di esempio?
kjc26ster,

1
Voglio dire, antepone, distacca l'elemento dalla sua posizione originale e lo inserisce in quello nuovo. D'altra parte, la funzione di distacco stacca semplicemente l'elemento selezionato e puoi salvarlo in una variabile per inserirlo nel DOM in un secondo momento. Il fatto è che la tua chiamata di distacco non è necessaria. Rimuovilo e otterrai lo stesso effetto.
Tim Büthe

1
Incredibile che le modifiche abbiano cambiato completamente questa risposta al punto che un'altra anno è stata aggiunta un anno dopo (identico all'originale) e ha ottenuto oltre 800 voti ...
hlscalon

96

Che dire di una soluzione 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);

Controlla.


8
Perché usare createDocumentFragment anziché semplicemente document.getElementById ('destination'). AppendChild (document.getElementById ('source'))?
Gunar Gessner,

6
@ GunarC.Gessner supponendo che sia necessario modificare l'oggetto di origine prima di aggiungerlo all'oggetto di destinazione, quindi l'approccio migliore è utilizzare il frammento che è un oggetto immaginario e non fa parte dell'albero DOM, si ottengono prestazioni migliori quando si modifica il oggetto sorgente quando è stato spostato dalla sua posizione originale (ora si trova all'interno del frammento) anziché modificarlo nella sua posizione iniziale prima di aggiungerlo.
Ali Bassam,

5
Voglio aggiungere per l'importanza di offrire una soluzione pura JavaScript. Non si deve presumere che jQuery sia sempre usato
Alexander Fradiani il

1
Domanda: aggiungendo il nodo figlio, stiamo perdendo gli eventi collegati?
jimasun,

1
La risposta alla mia domanda è sì, mantiene gli eventi allegati.
jimasun,

95

Se il punto in divcui vuoi inserire il tuo elemento contiene contenuti e desideri che l'elemento venga visualizzato dopo il contenuto principale:

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

Se il punto in divcui vuoi inserire il tuo elemento ha contenuto all'interno e vuoi mostrare l'elemento prima del contenuto principale:

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

Se il punto in divcui desideri inserire l'elemento è vuoto o desideri sostituirlo interamente:

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

Se si desidera duplicare un elemento prima di uno dei precedenti:

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

Sto trovando tutto il grassetto un po 'difficile da leggere, ma questa è la risposta più istruttiva, quindi ottiene il mio voto.
Michael Scheper,

32

Puoi usare:

Da inserire dopo,

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

Per inserire all'interno di un altro elemento,

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

20

Se vuoi una demo veloce e maggiori dettagli su come sposti gli elementi, prova questo link:

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


Ecco un breve esempio:

Per spostare SOPRA un elemento:

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

Per spostare DOPO un elemento:

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

Per spostarsi all'interno di un elemento, SOPRA TUTTI gli elementi all'interno di quel contenitore:

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

Per spostarsi all'interno di un elemento, DOPO TUTTI gli elementi all'interno di quel contenitore:

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

19

È possibile utilizzare il seguente codice per spostare l'origine nella destinazione

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

prova a lavorare codepen


11

Vecchia domanda ma arrivata qui perché ho bisogno di spostare il contenuto da un contenitore all'altro compresi tutti i listener di eventi .

jQuery non ha modo di farlo, ma lo fa appendChild della funzione DOM standard.

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

L'uso di appendChild rimuove il .source e lo posiziona nella destinazione inclusi i listener di eventi: https://developer.mozilla.org/en-US/docs/Web/API/Node.appendChild


6

Puoi anche provare:

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

Ma questo sovrascriverà completamente tutto ciò che hai #destination.


2
E spezza i listener di eventi sull'elemento spostato.
Igor Pomaranskiy

4

Ho notato un'enorme perdita di memoria e una differenza di prestazioni tra insertAfter& aftero insertBefore& before.. Se hai tonnellate di elementi DOM, o devi usare after()o before()all'interno di un evento MouseMove , la memoria del browser probabilmente aumenterà e le prossime operazioni saranno molto lente.

La soluzione che ho appena provato è usare invece before()inserBefore e insertAfter after().


Sembra un problema dipendente dall'implementazione del motore JavaScript. Con quale versione del browser e motore JS vedi questo?
Mark Richman,

1
Sono su Chrome versione 36.0.1985.125 e utilizzo jQuery v1.11.1. Associo una funzione all'evento mousemove, che sposta un semplice DIV verso il basso o verso l'alto l'elemento su cui si trova il mouse. Pertanto, questo evento e questa funzione vengono eseguiti trascinando il cursore. La perdita di memoria si verifica con after () e before (), se sposti il ​​cursore per 30 secondi + e scompare se uso invece insertAfter & insertBefore.
spetsnaz,

1
Aprirei un bug con Google su quello.
Mark Richman,

2

Puoi usare JavaScript puro, usando il appendChild()metodo ...

Il metodo appendChild () aggiunge un nodo come ultimo figlio di un nodo.

Suggerimento: se si desidera creare un nuovo paragrafo, con testo, ricordarsi di creare il testo come nodo Testo che si aggiunge al paragrafo, quindi aggiungere il paragrafo al documento.

È inoltre possibile utilizzare questo metodo per spostare un elemento da un elemento a un altro.

Suggerimento: utilizzare il metodo insertBefore () per inserire un nuovo nodo figlio prima di un nodo figlio specificato, esistente.

Quindi puoi farlo per fare il lavoro, questo è quello che ho creato per te, usando appendChild(), esegui e vedi come funziona per il tuo 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

Per completezza, c'è un altro approccio wrap()o wrapAll()menzionato in questo articolo . Quindi la domanda del PO potrebbe essere risolta da questo (cioè, supponendo <div id="destination" />che non esista ancora, il seguente approccio creerà un tale wrapper da zero - il PO non era chiaro se il wrapper esistesse o meno):

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

Sembra promettente. Tuttavia, quando stavo provando a fare $("[id^=row]").wrapAll("<fieldset></fieldset>")su più strutture nidificate come questa:

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

Li avvolge correttamente <div>...</div>e <input>...</input>MA QUALCUNO LASCIA <label>...</label>. Quindi ho finito per usare l'esplicito $("row1").append("#a_predefined_fieldset"). Quindi, YMMV.


0

miglioramento delle dimensioni sporco della risposta di Bekim Bacaj

div { border: 1px solid ; margin: 5px }
<div id="source" onclick="destination.appendChild(this)">click me</div>
<div id="destination" >...</div>

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.