如何将一个元素移动到另一个元素?


1688

我想将一个DIV元素移到另一个元素中。例如,我要移动此对象(包括所有孩子):

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

到这个:

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

这样我有:

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

21
只需使用$(target_element).append(to_be_inserted_element);
Mohammad Areeb Siddiqui 2013年

2
或:使用普通javascript的destination.appendChild(source)
luke

我们可以使用CSS来实现吗?那可能吗 ?
RajKumar Samala'3

6
@RajKumarSamala CSS不能更改HTML的结构,只能更改其表示形式。
Mark Richman

Answers:


38

曾经尝试过普通的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>


*某人在尝试增强帖子时,在演示代码段的全局事件 onclick前添加了关键字var-但这是错误的!
Bekim Bacaj

6
人们仍然认为jQuery等同于JavaScript真是令人惊讶。实际上,2017年不再需要jQuery。
nkkollaw

2
在2017年无需使用jquery,但有时候在每个项目中一次又一次地使用轻松而类似的功能有助于完成任务。我使用Cash-dom作为一种以跨浏览器友好的方式监听document.ready,window.load事件的简便方法。十分简单。
eballeste

1
将其更改为公认的答案,现在是2020年:)
Mark Richman

1
人们仍然认为jQuery等同于JavaScript真是令人惊讶。实际上,2020年将不再需要jQuery。
ii iml0sto1

1793

您可能要使用该appendTo函数(该函数会添加到元素的末尾):

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

或者,您可以使用prependTo函数(将其添加到元素的开头):

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

例:


23
警告这可能在jQuery mobile中无法正常工作,因为它可能会创建该元素的另一个副本。
Jordan Reiter 2012年

32
appenTo创建副本还是实际上将整个div移动到目标位置?(因为如果复制,则在通过id调用div时会产生错误)

50
这是一篇关于删除,替换和移动jQuery中元素的出色文章:elated.com/articles/jquery-removing-replacing-moving-elements
xhh 2012年

42
注意jQuery的文档appendTo状态元素被移动:it will be moved into the target (not cloned) and a new set consisting of the inserted element is returned- api.jquery.com/appendto
约翰ķ

15
您没有移动它,只是追加。下面的答案做了适当的移动。
亚伦

913

我的解决方案:

移动:

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

复制:

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

注意.detach()的用法。复制时,请注意不要复制ID。


86
最佳答案。接受的答案会创建一个副本,不会像问题所要求的那样移动元素。
paulscode 2013年

97
抱歉,但是Andrew Hare接受的答案是正确的-分离是不必要的。在上面的Pixic的JSFiddle中尝试一下-如果删除detach调用,则它的工作原理完全相同,即,它执行了移动,而不是复制。这只是其中的一项更改:jsfiddle.net/D46y5 如API中所述:api.jquery.com/appendTo:“如果将以此方式选择的元素插入DOM中其他位置的单个位置,则它将被移动到目标(未克隆)中,并返回包含插入元素的新集合”
约翰-非数字

8
@ John-NotANumber是正确的-这里不需要detach()。公认的答案是最好的,您只需要正确阅读文档即可。
LeonardChallis 2014年

11
appendTo文档还说:“但是,如果有多个目标元素,则将在第一个目标之后为每个目标创建插入元素的克隆副本,并返回新的集合(原始元素和克隆)。” 因此,在一般情况下,此解决方案也可以创建副本!
文森特·帕泽勒

大!或者,您可以使用它来更具体地说明要移动的位置$('#nodeToMove').insertAfter('#insertAfterThisElement');
Victor Augusto

108

我只是用过:

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

我从这里抓起的。


7
好吧,当您要保留该元素并稍后再重新插入时,分离很有用,但是在您的示例中,无论如何您都立即将其重新插入。
TimBüthe2012年

1
恐怕我不太了解您的意思,您能提供示例代码吗?
kjc26ster 2012年

1
我的意思是prependTo,将元素从其原始位置分离出来,然后将其插入到新元素中。另一方面,分离功能仅分离选定的元素,您可以将其保存在变量中,以便稍后将其插入到DOM中。问题是,您的分离调用是不必要的。删除它,您将获得相同的效果。
蒂姆·布斯(TimBüthe)2012年

1
令人难以置信的是,编辑完全改变了这个答案,以至于一年后又添加了另一个答案(与原始答案相同),并获得800多个投票...
hlscalon,

96

那么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);

一探究竟。


8
为什么使用createDocumentFragment而不是简单的document.getElementById('destination')。appendChild(document.getElementById('source'))?
Gunar Gessner

6
@ GunarC.Gessner假定您需要在将源对象添加到目标对象之前对其进行修改,然后最好的方法是使用属于虚构对象且不属于DOM树的片段,在修改源对象时,您可以获得更好的性能。源对象从其原始位置(现在位于片段内部)过渡后,而不是在附加位置之前在其原始位置进行修改。
阿里·巴萨姆

5
我想补充一下提供JavaScript纯解决方案的相关性。不应假定始终使用jQuery
Alexander Fradiani

1
问题:在附加子节点时,我们是否会丢失附加事件?
jimasun

1
我自己的问题的答案是肯定的,它确实保留了所附事件。
jimasun

95

如果div要放置元素的位置中包含内容,并且您希望该元素显示主要内容之后:

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

如果div要放置元素的位置中包含内容,并且您希望在主要内容之前显示该元素:

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

如果div要放置元素的位置为空,或者要完全替换它:

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

如果要在上述任何一项之前复制元素:

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

我发现所有黑体字都很难看懂,但这是最有用的答案,因此得到了我的好评。
Michael Scheper 2014年

32

您可以使用:

要在之后插入,

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

要插入另一个元素,

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

20

如果您需要快速演示,以及有关如何移动元素的更多详细信息,请尝试以下链接:

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


这是一个简短的示例:

要在元素上方移动:

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

要在元素之后移动:

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

要在元素内部移动,请在该容器内的所有元素上方:

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

要在元素内部移动,请在该容器内的所有元素之后:

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

19

您可以使用以下代码将源移至目标

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

尝试工作Codepen


11

这是个老问题,但是因为我需要将内容从一个容器移到包括所有事件监听器的另一个容器中,所以出现在这里。

jQuery没有方法,但是标准DOM函数appendChild有。

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

使用appendChild会删除.source并将其放置到目标(包括事件监听器)中:https : //developer.mozilla.org/en-US/docs/Web/API/Node.appendChild


6

您也可以尝试:

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

但这将完全覆盖您拥有的所有内容#destination


2
并在已移动的元素上中断事件侦听器。
伊戈尔·波马兰斯基

4

我注意到insertAfterafterinsertBefore&之间存在巨大的内存泄漏和性能差异before。如果您有大量的DOM元素,或者需要使用MouseMove事件after()before()在其中移动,浏览器内存可能会增加和明年业务将运行很慢。

我刚刚经历的解决方案是使用inserBefore代替before(),而使用insertAfter after()


这听起来像是JavaScript引擎实现相关的问题。您看到哪个浏览器版本和JS引擎?
马克·里奇曼

1
我使用的是Chrome版本36.0.1985.125,并使用jQuery v1.11.1。我在mousemove事件上绑定了一个函数,该事件将简单的DIV向下或向上移动鼠标悬停的元素。因此,此事件和功能在您拖动光标时运行。如果将光标移动30秒以上,则会在after()和before()发生内存泄漏,而如果我只是使用insertAfter和insertBefore代替,它将消失。
spetsnaz 2014年

1
我会在那个上与Google一起打开一个bug。
马克·里奇曼

2

您可以使用纯JavaScript,使用appendChild()方法...

appendChild()方法将节点追加为节点的最后一个子节点。

提示:如果要创建带有文本的新段落,请记住将文本创建为Text节点,然后将其附加到段落中,然后将该段落附加到文档中。

您也可以使用此方法将一个元素从一个元素移动到另一个元素。

提示:使用insertBefore()方法可在指定的现有子节点之前插入新的子节点。

因此,您可以执行此操作,这是我为您创建的,使用appendChild(),运行并查看它如何适用于您的案例:

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

为了完整起见,还有另一种方法wrap()wrapAll()中提到的这篇文章。因此,OP的问题可能会由此解决(也就是说,假设<div id="destination" />尚不存在,以下方法将从头开始创建这样的包装器-OP不清楚包装器是否已经存在):

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

听起来很有希望。但是,当我尝试$("[id^=row]").wrapAll("<fieldset></fieldset>")对多个嵌套结构执行以下操作时:

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

它正确地包装了那些<div>...</div><input>...</input>但是有所遗漏<label>...</label>。所以我最终使用显式$("row1").append("#a_predefined_fieldset")代替。因此,YMMV。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.