Jak przenieść element do innego elementu?


1688

Chciałbym przenieść jeden element DIV do innego. Na przykład chcę to przenieść (w tym wszystkie dzieci):

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

zaangażowany w to:

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

więc mam to:

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

21
Wystarczy użyć $ (element_elementowy) .append (to_be_inserted_element);
— Mohammad Areeb Siddiqui

2
Lub: destination.appendChild (źródło) przy użyciu zwykłego javascript
— Łukasz

czy możemy to osiągnąć za pomocą CSS? czy to jest możliwe ?
— RajKumar Samala

6
@RajKumarSamala CSS nie może zmieniać struktury HTML, tylko jego prezentację.
— Mark Richman,

Odpowiedzi:


38

Czy kiedykolwiek próbowałeś zwykłego 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>


* ktoś poprzedził globalne wydarzenie onclick fragmentu wersji demo słowem kluczowym varw swojej próbie ulepszenia posta - ale to źle!
— Bekim Bacaj,

6
To niesamowite, jak ludzie nadal myślą, że jQuery równa się JavaScript. Naprawdę nie ma już potrzeby korzystania z jQuery w 2017 roku.
— nkkollaw

2
w 2017 roku nie ma potrzeby wysyłania jquery, ale czasami pomaga to zastosować coś lżejszego i podobnego do zadań, które wykonujesz w kółko w każdym projekcie. używam cash-dom jako łatwego sposobu na nasłuchiwanie zdarzeń document.ready, window.load w sposób przyjazny dla różnych przeglądarek. bułka z masłem.
— eballeste,

1
Zmieniając to na przyjętą odpowiedź, teraz jest 2020 r. :)
— Mark Richman

1
To niesamowite, jak ludzie nadal myślą, że jQuery równa się JavaScript. Naprawdę nie ma już potrzeby korzystania z jQuery w 2020 roku.
— ii iml0sto1

1793

Możesz użyć appendTofunkcji (która dodaje się do końca elementu):

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

Alternatywnie możesz użyć prependTofunkcji (która dodaje się do początku elementu):

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

Przykład:


23
Ostrzeżenie, że może to nie działać poprawnie w jQuery mobile, ponieważ może zamiast tego utworzyć kolejną kopię elementu.
— Jordan Reiter,

32
czy appenTo tworzy kopię, czy faktycznie przenosi cały div do miejsca docelowego? (ponieważ jeśli kopiuje,

50
Oto doskonały artykuł na temat usuwania, zastępowania i przenoszenia elementów w jQuery: elated.com/articles/jquery-removing-replacing-moving-elements
— xhh

42
Zwróć uwagę na dokumentację jQuery dla appendTo stwierdza, że ​​element został przeniesiony: 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
Nie przenosisz go, tylko dołączasz. Poniższa odpowiedź zawiera właściwy ruch.
— Aaron

913

moje rozwiązanie:

RUSZAJ SIĘ:

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

KOPIUJ:

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

Zwróć uwagę na użycie .detach (). Podczas kopiowania uważaj, aby nie powielać identyfikatorów.


86
Najlepsza odpowiedź. Zaakceptowana odpowiedź tworzy kopię, nie przesuwa elementu tak, jak pyta pytanie.
— paulscode

97
Przepraszamy, ale zaakceptowana odpowiedź Andrew Hare'a jest poprawna - odłączanie jest niepotrzebne. Wypróbuj to w JSFiddle Pixic powyżej - jeśli usuniesz wywołania detach, działa dokładnie tak samo, tzn. Wykonuje ruch, NIE kopiuje. Oto rozwidlenie z tylko jedną zmianą: jsfiddle.net/D46y5 Jak udokumentowano w interfejsie API: api.jquery.com/appendTo : „Jeśli element wybrany w ten sposób zostanie wstawiony w jedno miejsce w innym miejscu w DOM, zostanie on przeniesiony do celu (nie sklonowany) i zwracany jest nowy zestaw składający się z wstawionego elementu ”
— John - Not A Number

8
@ John-NotANumber ma rację - detach () nie jest tutaj potrzebne. Przyjęta odpowiedź JEST najlepsza, wystarczy właściwie przeczytać dokumentację.
— LeonardChallis,

11
Dokumentacja appendTo mówi również: „Jeśli istnieje więcej niż jeden element docelowy, sklonowane kopie wstawionego elementu zostaną utworzone dla każdego celu po pierwszym, a ten nowy zestaw (oryginalny element plus klony) zostanie zwrócony.”. Tak więc w ogólnym przypadku to rozwiązanie MOŻE również tworzyć kopie!
— Vincent Pazeller

świetny! Możesz też użyć tego, aby sprecyzować, gdzie się przenieść$('#nodeToMove').insertAfter('#insertAfterThisElement');
— Victor Augusto

108

Właśnie użyłem:

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

Który stąd złapałem .


7
Cóż, odłączanie jest przydatne, gdy chcesz zatrzymać element i włożyć go później, ale w twoim przykładzie i tak wstawiasz go natychmiast.
— Tim Büthe,

1
Obawiam się, że nie do końca rozumiem, o co ci chodzi, czy możesz podać przykładowy kod?
— kjc26ster,

1
Mam na myśli, prependTo, odłącza element od jego pierwotnej pozycji i wstawia go do nowego. Z drugiej strony funkcja odłączania po prostu odłącza wybrany element i można zapisać go w zmiennej, aby wstawić go do DOM w późniejszym czasie. Chodzi o to, że połączenie typu „odłącz” jest niepotrzebne. Usuń go, a osiągniesz ten sam efekt.
— Tim Büthe,

1
Niesamowite, że zmiany całkowicie zmieniły tę odpowiedź do tego stopnia, że ​​rok później została dodana inna odpowiedź (identyczna z oryginałem) i uzyskała ponad 800 głosów pozytywnych ...
— hlscalon

96

Co z rozwiązaniem 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);

Sprawdź to.


8
Dlaczego warto korzystać z createDocumentFragment zamiast po prostu document.getElementById ('destination'). AppendChild (document.getElementById ('source'))?
— Gunar Gessner

6
@ GunarC.Gessner zakładając, że musisz zmodyfikować obiekt źródłowy przed dodaniem go do obiektu docelowego, wówczas najlepszym podejściem jest użycie fragmentu, który jest urojonym obiektem i nie jest częścią drzewa DOM, uzyskujesz lepszą wydajność podczas modyfikowania obiekt źródłowy, gdy został przeniesiony ze swojego pierwotnego miejsca (teraz znajduje się wewnątrz fragmentu) zamiast modyfikować go w swoim pierwotnym miejscu przed dołączeniem.
— Ali Bassam,

5
Chcę dodać do znaczenia oferowania czystego rozwiązania JavaScript. Nie należy zakładać, że jQuery jest zawsze używane
— Alexander Fradiani

1
Pytanie: Czy dołączając węzeł potomny tracimy dołączone zdarzenia?
— jimasun

1
Odpowiedź na moje własne pytanie brzmi: tak, zachowuje załączone wydarzenia.
— jimasun

95

Jeśli w divmiejscu, w którym chcesz umieścić element, znajduje się treść, a chcesz, aby element wyświetlał się po głównej zawartości:

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

Jeśli w divmiejscu, w którym chcesz umieścić element, znajduje się zawartość, a chcesz pokazać element przed główną treścią:

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

Jeśli miejsce, w divktórym chcesz umieścić element, jest puste lub chcesz go całkowicie zastąpić :

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

Jeśli chcesz powielić element przed którymkolwiek z powyższych:

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

Uważam, że cała pogrubiona czcionka jest nieco trudna do odczytania, ale jest to najbardziej pouczająca odpowiedź, więc zyskuje moje poparcie.
— Michael Scheper

32

Możesz użyć:

Aby wstawić po,

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

Aby wstawić do innego elementu,

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

20

Jeśli chcesz mieć szybkie demo i więcej szczegółów na temat przenoszenia elementów, wypróbuj ten link:

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


Oto krótki przykład:

Aby przenieść POWYŻEJ elementu:

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

Aby przejść PO elemencie:

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

Aby poruszać się w elemencie, POWYŻEJ WSZYSTKIE elementy w tym kontenerze:

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

Aby poruszać się wewnątrz elementu, PO WSZYSTKICH elementach w tym kontenerze:

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

19

Możesz użyć następującego kodu, aby przenieść źródło do miejsca docelowego

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

spróbuj działać codepen


11

Stare pytanie, ale dotarłem tutaj, ponieważ muszę przenosić zawartość z jednego kontenera do drugiego, w tym wszystkich detektorów zdarzeń .

jQuery nie ma na to sposobu, ale robi to standardowa funkcja DOM appendChild.

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

Użycie appendChild usuwa .source i umieszcza go w celu, w tym w detektorach zdarzeń: https://developer.mozilla.org/en-US/docs/Web/API/Node.appendChild


6

Możesz także spróbować:

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

Ale to całkowicie zastąpi wszystko, co masz #destination.


2
I przerywaj detektory zdarzeń na przeniesionym elemencie.
— Igor Pomaranskiy

4

Zauważyłem ogromny przeciek pamięci i różnicę wydajności między insertAfteri afterlub insertBeforei before. Jeśli masz mnóstwo elementów DOM lub potrzebujesz użyć after()lub before()wewnątrz zdarzenia MouseMove , pamięć przeglądarki prawdopodobnie wzrośnie, a kolejne operacje będą przebiegać naprawdę wolno.

Rozwiązaniem, którego właśnie doświadczyłem, jest użycie insertBefore zamiast before()i insertAfter zamiast after().


To brzmi jak problem związany z implementacją silnika JavaScript. W jakiej wersji przeglądarki i silniku JS to widzisz?
— Mark Richman

1
Używam przeglądarki Chrome w wersji 36.0.1985.125 i korzystam z jQuery v1.11.1. W zdarzeniu mousemove wiążę funkcję, która przesuwa prosty DIV w dół lub w górę elementu, nad którym znajduje się mysz. Dlatego to zdarzenie i funkcja działają podczas przeciągania kursora. Wyciek pamięci występuje w przypadku funkcji after () i before (), jeśli przesuwasz kursor przez 30 sekund +, i znika, jeśli zamiast tego użyję insertAfter i insertBefore.
— spetsnaz

1
W tym przypadku otworzyłbym błąd w Google.
— Mark Richman

2

Możesz użyć czystego JavaScript, używając appendChild()metody ...

Metoda appendChild () dołącza węzeł jako ostatnie dziecko węzła.

Wskazówka: Jeśli chcesz utworzyć nowy akapit z tekstem, pamiętaj o utworzeniu tekstu jako węzła tekstowego, który dołączasz do akapitu, a następnie dołącz akapit do dokumentu.

Możesz także użyć tej metody, aby przenieść element z jednego elementu do drugiego.

Wskazówka: Użyj metody insertBefore (), aby wstawić nowy węzeł potomny przed określonym, istniejącym węzłem potomnym.

Aby to zrobić, możesz to zrobić, oto, co dla ciebie stworzyłem, używając appendChild(), uruchamiając i sprawdzając, jak to działa w twoim przypadku:

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

Dla kompletności istnieje inne podejście wrap()lub wrapAll()wspomniane w tym artykule . Pytanie OP może więc zostać rozwiązane w ten sposób (tzn. Zakładając, że <div id="destination" />jeszcze nie istnieje, poniższe podejście utworzy takie opakowanie od zera - PO nie było jasne, czy opakowanie już istnieje, czy nie):

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

Brzmi obiecująco. Jednak gdy próbowałem zrobić $("[id^=row]").wrapAll("<fieldset></fieldset>")na wielu zagnieżdżonych strukturach, takich jak to:

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

To właściwie zawija te <div>...</div>i <input>...</input>ale jakoś pominięto <label>...</label>. Więc $("row1").append("#a_predefined_fieldset")zamiast tego użyłem jawnego . Więc YMMV.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.