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.