Wie verschiebe ich ein Element in ein anderes Element?

1688

Ich möchte ein DIV-Element in ein anderes verschieben. Zum Beispiel möchte ich dies verschieben (einschließlich aller Kinder):

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

das sehr gut finden:

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

damit ich das habe:

<div id="destination">
  <div id="source">
    ...
  </div>
</div>
Mark Richman
quelle
21
Verwenden Sie einfach $ (target_element) .append (to_be_inserted_element);
Mohammad Areeb Siddiqui
2
Oder: destination.appendChild (Quelle) mit einfachem Javascript
Luke
Können wir dies mit CSS erreichen? ist das möglich ?
RajKumar Samala
6
@RajKumarSamala CSS kann die Struktur des HTML-Codes nicht ändern, nur seine Darstellung.
Mark Richman

Antworten:

38

Haben Sie schon einmal einfaches JavaScript ausprobiert ... 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>

Bekim Bacaj
quelle
* Jemand hat dem globalen Ereignis onclick des Demo-Snippets das Schlüsselwort vorangestellt var, um den Beitrag zu verbessern - aber das ist falsch!
Bekim Bacaj
6
Es ist erstaunlich, wie die Leute immer noch denken, dass jQuery gleich JavaScript ist. 2017 ist jQuery eigentlich nicht mehr nötig.
Nkkollaw
2
2017 ist keine Abfrage erforderlich, aber manchmal hilft es, etwas Leichteres und Ähnliches für Aufgaben zu verwenden, die Sie in jedem einzelnen Projekt immer wieder erledigen. Ich benutze Cash-Dom als eine einfache Möglichkeit, auf document.ready, window.load-Ereignisse browserübergreifend zu warten. kinderleicht.
Eballeste
1
Ändern Sie dies in die akzeptierte Antwort, jetzt, da es 2020 ist :)
Mark Richman
1
Es ist erstaunlich, wie die Leute immer noch denken, dass jQuery gleich JavaScript ist. Eigentlich braucht man jQuery im Jahr 2020 nicht mehr.
ii iml0sto1
1794

Möglicherweise möchten Sie die appendToFunktion verwenden (die am Ende des Elements hinzugefügt wird):

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

Alternativ können Sie die prependToFunktion verwenden (die am Anfang des Elements hinzugefügt wird):

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

Beispiel:

Andrew Hare
quelle
23
Eine Warnung, dass dies in jQuery Mobile möglicherweise nicht richtig funktioniert, da stattdessen möglicherweise eine weitere Kopie des Elements erstellt wird.
Jordan Reiter
32
Erstellt der Anhang eine Kopie oder verschiebt er tatsächlich das gesamte Div an das Ziel? (denn wenn es kopiert, würde es Fehler aufrufen, wenn das div durch die ID
50
Hier ist ein ausgezeichneter Artikel über das Entfernen, Ersetzen und Verschieben von Elementen in jQuery: elated.com/articles/jquery-removing-replacing-moving-elements
xhh
42
Beachten Sie die jQuery-Dokumentation für appendTo, in der angegeben ist, dass das Element verschoben wurde: 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
Sie bewegen es nicht, sondern hängen es an. Die folgende Antwort macht einen richtigen MOVE.
Aaron
913

meine Lösung:

BEWEGUNG:

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

KOPIEREN:

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

Beachten Sie die Verwendung von .detach (). Achten Sie beim Kopieren darauf, dass Sie keine IDs duplizieren.

Alejandro Illecas
quelle
86
Beste Antwort. Die akzeptierte Antwort erstellt eine Kopie und verschiebt das Element nicht so, wie es die Frage verlangt.
Paulscode
97
Entschuldigung, aber Andrew Hares akzeptierte Antwort ist richtig - die Trennung ist unnötig. Versuchen Sie es in Pixics JSFiddle oben - wenn Sie die Trennaufrufe entfernen, funktioniert es genauso, dh es wird verschoben, NICHT kopiert. Hier ist die Verzweigung mit nur dieser einen Änderung: jsfiddle.net/D46y5 Wie in der API dokumentiert: api.jquery.com/appendTo : "Wenn ein auf diese Weise ausgewähltes Element an einer anderen Stelle im DOM eingefügt wird, wird es verschoben in das Ziel (nicht geklont) und ein neuer Satz bestehend aus dem eingefügten Element wird zurückgegeben "
John - Not A Number
8
@ John-NotANumber ist richtig - remove () wird hier nicht benötigt. Die akzeptierte Antwort ist die beste, Sie müssen nur die Dokumentation richtig lesen.
LeonardChallis
11
In der appendTo-Dokumentation heißt es außerdem: "Wenn jedoch mehr als ein Zielelement vorhanden ist, werden nach dem ersten für jedes Ziel geklonte Kopien des eingefügten Elements erstellt und dieser neue Satz (das ursprüngliche Element plus Klone) zurückgegeben." Im Allgemeinen kann diese Lösung also auch Kopien erstellen!
Vincent Pazeller
groß! Oder Sie können dies verwenden, um genauer $('#nodeToMove').insertAfter('#insertAfterThisElement');
Victor Augusto
108

Ich habe gerade verwendet:

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

Was ich von hier gepackt habe .

kjc26ster
quelle
7
Nun, Trennen ist nützlich, wenn Sie das Element festhalten und später wieder einfügen möchten, aber in Ihrem Beispiel setzen Sie es trotzdem sofort wieder ein.
Tim Büthe
1
Ich fürchte, ich bin mir nicht ganz sicher, worauf Sie hinaus wollen. Können Sie Beispielcode bereitstellen?
kjc26ster
1
Ich meine, prependTo löst das Element von seiner ursprünglichen Position und fügt es an der neuen ein. Die Trennfunktion hingegen trennt nur das ausgewählte Element und Sie können es in einer Variablen speichern, um es zu einem späteren Zeitpunkt in das DOM einzufügen. Die Sache ist, Ihr Anruf zu trennen ist unnötig. Entfernen Sie es und Sie werden den gleichen Effekt erzielen.
Tim Büthe
1
Unglaublich, dass die Änderungen diese Antwort vollständig geändert haben, bis ein Jahr später eine weitere Antwort hinzugefügt wurde (identisch mit dem Original) und mehr als 800 Upvotes erhalten hat ...
hlscalon
96

Was ist mit einer JavaScript- Lösung?

// 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);

Hör zu.

Ali Bassam
quelle
8
Warum createDocumentFragment anstelle von document.getElementById ('Ziel'). AppendChild (document.getElementById ('Quelle')) verwenden?
Gunar Gessner
6
@ GunarC.Gessner Angenommen, Sie müssen das Quellobjekt ändern, bevor Sie es zum Zielobjekt hinzufügen. Der beste Ansatz besteht darin, das Fragment zu verwenden, das ein imaginäres Objekt ist und nicht Teil des DOM-Baums ist. Sie erhalten eine bessere Leistung, wenn Sie das ändern Quellobjekt, wenn es von seinem ursprünglichen Ort (jetzt befindet es sich innerhalb des Fragments) überführt wurde, anstatt es an seinem ursprünglichen Ort zu ändern, bevor es angehängt wird.
Ali Bassam
5
Ich möchte für die Relevanz des Angebots einer reinen JavaScript-Lösung hinzufügen. Es sollte nicht angenommen werden, dass jQuery immer verwendet wird
Alexander Fradiani
1
Frage: Verlieren wir beim Anhängen des untergeordneten Knotens die angehängten Ereignisse?
Jimasun
1
Die Antwort auf meine eigene Frage lautet: Ja, die angehängten Ereignisse bleiben erhalten.
Jimasun
95

Wenn der Ort, an divdem Sie Ihr Element platzieren möchten, Inhalt enthält und das Element nach dem Hauptinhalt angezeigt werden soll:

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

Wenn der Ort, an divdem Sie Ihr Element platzieren möchten, Inhalt enthält und Sie das Element vor dem Hauptinhalt anzeigen möchten :

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

Wenn der Ort, an divdem Sie Ihr Element platzieren möchten, leer ist oder Sie es vollständig ersetzen möchten :

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

Wenn Sie ein Element vor einem der oben genannten Elemente duplizieren möchten:

$("#destination").append($("#source").clone());
// etc.
sbaaaang
quelle
Ich finde das Fettdruck etwas schwer zu lesen, aber dies ist die informativste Antwort, daher wird es positiv bewertet.
Michael Scheper
32

Sie können verwenden:

Einfügen nach,

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

Um in ein anderes Element einzufügen,

jQuery("#source").appendTo("#destination");
Subrahmanyam
quelle
20

Wenn Sie eine kurze Demo und weitere Details zum Verschieben von Elementen wünschen, versuchen Sie diesen Link:

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


Hier ist ein kurzes Beispiel:

So bewegen Sie sich über ein Element:

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

So bewegen Sie sich NACH einem Element:

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

Um sich innerhalb eines Elements zu bewegen, ÜBER ALLEN Elementen in diesem Container:

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

Um sich innerhalb eines Elements zu bewegen, NACH ALLEN Elementen in diesem Container:

$('.whatToMove').appendTo('.whereToMove');
Dan
quelle
19

Sie können den folgenden Code verwenden, um die Quelle zum Ziel zu verschieben

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

Versuchen Sie, Codepen zu arbeiten

Subodh Ghulaxe
quelle
11

Alte Frage, aber ich bin hierher gekommen, weil ich Inhalte von einem Container in einen anderen verschieben muss, einschließlich aller Ereignis-Listener .

jQuery hat keine Möglichkeit dazu, aber die Standard-DOM-Funktion appendChild.

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

Durch die Verwendung von appendChild wird die .source entfernt und in das Ziel einschließlich der Ereignis-Listener eingefügt: https://developer.mozilla.org/en-US/docs/Web/API/Node.appendChild

HMR
quelle
6

Sie können auch versuchen:

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

Dies wird jedoch alles, was Sie haben, vollständig überschreiben #destination.

Tamas
quelle
2
Und brechen Sie Ereignis-Listener für das verschobene Element.
Igor Pomaranskiy
4

Ich habe einen großen Speicherverlust und Leistungsunterschied zwischen insertAfter& afteroder insertBefore& beforefestgestellt. Wenn Sie Tonnen von DOM-Elementen haben oder ein MouseMove-Ereignis verwenden müssen after()oder sich before()darin befinden , wird der Browserspeicher wahrscheinlich größer und die nächsten Vorgänge werden sehr langsam ausgeführt.

Die Lösung, die ich gerade erlebt habe, besteht darin, stattdessen before()inserBefore und stattdessen insertAfter zu verwenden after().

spetsnaz
quelle
Dies klingt nach einem von der Implementierung der JavaScript-Engine abhängigen Problem. Mit welcher Browserversion und JS-Engine sehen Sie das?
Mark Richman
1
Ich bin auf Chrome Version 36.0.1985.125 und verwende jQuery v1.11.1. Ich binde eine Funktion für ein Mausbewegungsereignis, die einen einfachen DIV nach unten oder oben des Elements bewegt, über dem sich die Maus befindet. Daher wird dieses Ereignis und diese Funktion ausgeführt, während Sie den Cursor ziehen. Der Speicherverlust tritt bei after () und before () auf, wenn Sie den Cursor 30 Sekunden lang + bewegen, und verschwindet, wenn ich stattdessen nur insertAfter & insertBefore verwende.
Spetsnaz
1
Ich würde einen Fehler mit Google auf diesem öffnen.
Mark Richman
2

Sie können reines JavaScript verwenden, indem Sie die appendChild()Methode ...

Die appendChild () -Methode hängt einen Knoten als letztes untergeordnetes Element eines Knotens an.

Tipp: Wenn Sie einen neuen Absatz mit Text erstellen möchten, müssen Sie den Text als Textknoten erstellen, den Sie an den Absatz anhängen, und dann den Absatz an das Dokument anhängen.

Mit dieser Methode können Sie auch ein Element von einem Element in ein anderes verschieben.

Tipp: Verwenden Sie die Methode insertBefore (), um einen neuen untergeordneten Knoten vor einem angegebenen, vorhandenen untergeordneten Knoten einzufügen.

Damit Sie den Job erledigen können, habe ich Folgendes für Sie erstellt, verwendet appendChild(), ausgeführt und gesehen, wie es für Ihren Fall funktioniert:

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>

Alireza
quelle
0

Der Vollständigkeit halber gibt es einen anderen Ansatz wrap()oder wrapAll()wird in diesem Artikel erwähnt . Die Frage des OP könnte also möglicherweise dadurch gelöst werden (das heißt, unter der Annahme, dass der <div id="destination" />Wrapper noch nicht existiert, wird der folgende Ansatz von Grund auf neu erstellt - dem OP war nicht klar, ob der Wrapper bereits existiert oder nicht):

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

Es klingt vielversprechend. Als ich jedoch versuchte, dies $("[id^=row]").wrapAll("<fieldset></fieldset>")mit mehreren verschachtelten Strukturen wie folgt zu tun :

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

Es verpackt diese korrekt <div>...</div>und <input>...</input>ABER VERLÄSST AUF irgendeine Weise die <label>...</label>. Also habe ich $("row1").append("#a_predefined_fieldset")stattdessen das Explizite verwendet. Also, YMMV.

RayLuo
quelle