1904

I would like to move one DIV element inside another. For example, I want to move this (including all children):

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

into this:

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

so that I have this:

<div id="destination">
  <div id="source">
    ...
  </div>
</div>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Mark Richman
  • 28,948
  • 25
  • 99
  • 159

16 Answers16

1934

You may want to use the appendTo function (which adds to the end of the element):

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

Alternatively you could use the prependTo function (which adds to the beginning of the element):

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

Example:

$("#appendTo").click(function() {
  $("#moveMeIntoMain").appendTo($("#main"));
});
$("#prependTo").click(function() {
  $("#moveMeIntoMain").prependTo($("#main"));
});
#main {
  border: 2px solid blue;
  min-height: 100px;
}

.moveMeIntoMain {
  border: 1px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="main">main</div>
<div id="moveMeIntoMain" class="moveMeIntoMain">move me to main</div>

<button id="appendTo">appendTo main</button>
<button id="prependTo">prependTo main</button>
Clonkex
  • 3,373
  • 7
  • 38
  • 55
Andrew Hare
  • 344,730
  • 71
  • 640
  • 635
  • 25
    A warning that this may not work correctly in jQuery mobile, as it may create another copy of the element instead. – Jordan Reiter Jun 19 '12 at 14:07
  • 33
    does the appenTo create a copy or actually moves the whole div to the destination? (because if it copies, it would create erros when calling the div by the id) –  Jul 12 '12 at 22:04
  • 55
    Here is an excellent article on Removing, Replacing and Moving Elements in jQuery: http://www.elated.com/articles/jquery-removing-replacing-moving-elements/ – xhh Dec 03 '12 at 07:55
  • 47
    Note the jQuery documentation for appendTo states the element is moved: `it will be moved into the target (not cloned) and a new set consisting of the inserted element is returned` - http://api.jquery.com/appendto/ – John K Jan 13 '14 at 01:10
  • 18
    You are not moving it, just appending. Below answer does a proper MOVE. – Aaron May 28 '14 at 03:42
  • 10
    The documentation also says: "If there is more than one target element, however, cloned copies of the inserted element will be created for each target after the first, and that new set (the original element plus clones) is returned.". So in the general case, this solution CAN create copies! – Vincent Pazeller Feb 16 '15 at 09:57
1021

My solution:

Move:

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

copy:

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

Note the usage of .detach(). When copying, be careful that you are not duplicating IDs.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Alejandro Illecas
  • 10,563
  • 1
  • 14
  • 5
  • 93
    Best answer. Accepted answer creates a copy, doesn't move the element like the question asks for. – paulscode Dec 17 '13 at 19:02
  • 108
    Sorry, but Andrew Hare's accepted answer is correct - the detach is unnecessary. Try it in Pixic's JSFiddle above - if you remove the detach calls it works exactly the same, i.e. it does a move, NOT a copy. Here's the fork with just that one change: http://jsfiddle.net/D46y5/ As documented in the API: https://api.jquery.com/appendTo/ : "If an element selected this way is inserted into a single location elsewhere in the DOM, it will be moved into the target (not cloned) and a new set consisting of the inserted element is returned" – John - Not A Number Feb 04 '14 at 04:34
153

Use a vanilla JavaScript solution:

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

Check it out.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ali Bassam
  • 9,691
  • 23
  • 67
  • 117
  • 28
    Why using createDocumentFragment instead of simply document.getElementById('destination').appendChild(document.getElementById('source'))? – Gunar Gessner Feb 16 '16 at 01:45
117

Try plain JavaScript? destination.appendChild(source);.

addEventListener("click", () => document.getElementById("destination").appendChild(document.getElementById("source")));
div {
  margin: .1em;
}

#destination {
  border: solid 1px red;
}

#source {
  border: solid 1px gray;
}
<div id="destination">
  ###
</div>
<div id="source">
  ***
</div>
sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
Bekim Bacaj
  • 5,707
  • 2
  • 24
  • 26
  • 2
    _“Editing is important for keeping posts clear, relevant, and up-to-date. If you are not comfortable with the idea of your contributions being collaboratively edited by other trusted users, this may not be the site for you.”_ — from the [help center](/help/editing). – Sebastian Simon May 21 '23 at 03:08
111

I just used:

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

Which I grabbed from here.

Cᴏʀʏ
  • 105,112
  • 20
  • 162
  • 194
kjc26ster
  • 1,237
  • 1
  • 9
  • 8
  • 10
    Well, detach is useful when you want to hold on to the element and reinsert it later on, but in your example you reinsert it instantly anyway. – Tim Büthe Sep 27 '12 at 15:56
100

If the div where you want to put your element has content inside, and you want the element to show after the main content:

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

If the div where you want to put your element has content inside, and you want to show the element before the main content:

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

If the div where you want to put your element is empty, or you want to replace it entirely:

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

If you want to duplicate an element before any of the above:

$("#destination").append($("#source").clone());
// etc.
OrangeDog
  • 36,653
  • 12
  • 122
  • 207
itsme
  • 48,972
  • 96
  • 224
  • 345
40

You can use:

To insert after,

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

To insert inside another element,

jQuery("#source").appendTo("#destination");
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Subrahmanyam
  • 401
  • 4
  • 2
27

You can use the following code to move the source to the destination:

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

Try the working CodePen.

function move() {
 jQuery("#source")
   .detach()
   .appendTo('#destination');
}
#source{
  background-color: red;
  color: #ffffff;
  display: inline-block;
  padding: 35px;
}
#destination{
  background-color:blue;
  color: #ffffff;
  display: inline-block;
  padding: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="source">
I am source
</div>

<div id="destination">
I am destination
</div>

<button onclick="move();">Move</button>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Subodh Ghulaxe
  • 18,333
  • 14
  • 83
  • 102
24

If you want a quick demo and more details about how you move elements, try this link:

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


Here is a short example:

To move ABOVE an element:

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

To move AFTER an element:

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

To move inside an element, ABOVE ALL elements inside that container:

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

To move inside an element, AFTER ALL elements inside that container:

$('.whatToMove').appendTo('.whereToMove');
Dan
  • 715
  • 8
  • 12
14

I need to move content from one container to another including all the event listeners. jQuery doesn't have a way to do it, but the standard DOM function appendChild does.

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

Using appendChild removes the .source* and places it into target including its event listeners: Node.appendChild() (MDN)

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
HMR
  • 37,593
  • 24
  • 91
  • 160
10

You may also try:

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

But this will completely overwrite anything you have in #destination.

frb
  • 3,738
  • 2
  • 21
  • 51
Tamas
  • 326
  • 4
  • 9
9

You can use pure JavaScript, using appendChild() method...

The appendChild() method appends a node as the last child of a node.

Tip: If you want to create a new paragraph, with text, remember to create the text as a Text node which you append to the paragraph, then append the paragraph to the document.

You can also use this method to move an element from one element to another.

Tip: Use the insertBefore() method to insert a new child node before a specified, existing, child node.

So you can do that to do the job, this is what I created for you, using appendChild(), run and see how it works for your case:

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
  • 100,211
  • 27
  • 269
  • 172
7

I noticed huge memory leak & performance difference between insertAfter & after or insertBefore & before .. If you have tons of DOM elements, or you need to use after() or before() inside a MouseMove event, the browser memory will probably increase and next operations will run really slow.

The solution I've just experienced is to use inserBefore instead before() and insertAfter instead after().

AI Perera
  • 3
  • 3
spetsnaz
  • 1,181
  • 1
  • 14
  • 11
6

Dirty size improvement of Bekim Bacaj's answer:

div { border: 1px solid ; margin: 5px }
<div id="source" onclick="destination.appendChild(this)">click me</div>
<div id="destination" >...</div>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Kamil Kiełczewski
  • 85,173
  • 29
  • 368
  • 345
3

For the sake of completeness, there is another approach wrap() or wrapAll() mentioned in this article. So the OP's question could possibly be solved by this (that is, assuming the <div id="destination" /> does not yet exist, the following approach will create such a wrapper from scratch - the OP was not clear about whether the wrapper already exists or not):

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

It sounds promising. However, when I was trying to do $("[id^=row]").wrapAll("<fieldset></fieldset>") on multiple nested structure like this:

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

It correctly wraps those <div>...</div> and <input>...</input> BUT SOMEHOW LEAVES OUT the <label>...</label>. So I ended up use the explicit $("row1").append("#a_predefined_fieldset") instead. So, YMMV.

RayLuo
  • 17,257
  • 6
  • 88
  • 73
0

The .appendChild does precisely that - basically a cut& paste.

It moves the selected element and all of its child nodes.

Ronnie Royston
  • 16,778
  • 6
  • 77
  • 91