关于javascript:如何将一个元素移动到另一个元素中?

How to move an element into another element?

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

1
...

进入这个:

1
...

所以我有了这个:

1
    ...

  • 只需使用$(target_element).append(to_be_inserted_element);
  • 或:destination.appendchild(source),使用纯javascript
  • 我们能用CSS实现这一点吗?有可能吗?
  • @Rajkumarsamala的CSS不能改变HTML的结构,只能改变其表示形式。


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

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

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

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

例子:

1
2
3
4
5
6
$("#appendTo").click(function() {
  $("#moveMeIntoMain").appendTo($("#main"));
});
$("#prependTo").click(function() {
  $("#moveMeIntoMain").prependTo($("#main"));
});
1
2
3
4
5
6
7
8
#main {
  border: 2px solid blue;
  min-height: 100px;
}

.moveMeIntoMain {
  border: 1px solid red;
}
1
2
3
4
5
6
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
main
move me to main

<button id="appendTo">appendTo main</button>
<button id="prependTo">prependTo main</button>

  • 警告:这可能无法在jquery mobile中正常工作,因为它可能会创建元素的另一个副本。
  • AppTo是创建一个副本,还是实际将整个DIV移动到目的地?(因为如果它复制,它将在按ID调用DIV时创建错误)
  • 在jquery Mobile为我工作。谢谢!
  • "目的地"应该是"$"("目的地")':$("来源").Appendto($("目的地"));
  • @来自文档的user606696:"target:选择器、元素、html字符串或jquery对象"。
  • 下面是一篇关于jquery:elated.com/article s/jquery-removing-replacing-moving-element&zwnj;&8203;s中删除、替换和移动元素的优秀文章。
  • 它按文字正确工作。appendto()的参数是作为字符串的选择器,而不是jquery对象。
  • 注意,appendto的jquery文档说明元素已被移动:it will be moved into the target (not cloned) and a new set consisting of the inserted element is returned-api.jquery.com/appendto
  • 你没有移动它,只是附加。下面的答案是正确的。
  • 这个副本。不动。@Alejandro Illecas的回答动作。
  • 这个动作,不复制。请参阅上面由约翰K列出的实际文档,而不是随机的人发布错误的评论,即使他发布了。
  • 文档还说:"但是,如果有多个目标元素,那么将在第一个元素之后为每个目标创建插入元素的克隆副本,并返回新的集合(原始元素加上克隆)。"所以在一般情况下,这个解决方案可以创建副本!
  • 这会复制元素,但不会移动它…
  • 如果您看到创建的副本,可能与上面@vincentpazeller关于存在多个目标的评论有关。在我的情况下(把
  • 移到空的中),解决这个问题的方法就是在我打电话给.children()时简单地加上.last()。创建副本的修复前代码:$(this).appendTo($(this).prev().children("ol"));。按预期修复移动元素后的代码:$(this).appendTo($(this).prev().children("ol").last());
  • 如果要将所有内容移动到特定的DIV之后,还可以使用insertafter函数。这将在指定的id:api.jquery.com/insertafter之后移动一个div。


我的解决方案:

移动:

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

复印件:

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

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

  • 为此解决方案制作了一个jsFiddle:jsFiddle.net/pixic/8vrde
  • 最佳答案。接受的答案会创建一个副本,不会像问题要求的那样移动元素。
  • 抱歉,但安德鲁·黑尔接受的答案是正确的——没有必要分离。在上面Pixic的jsFiddle中尝试一下——如果移除分离调用,它的工作方式完全相同,即它执行移动,而不是复制。这里有一个分叉,只有一个变化:jsfiddle.net/d46y5,如api:api.jquery.com/appendto中所述:"如果以这种方式选择的元素被插入到dom中的其他位置,它将被移动到目标中(不是克隆的),并返回由插入元素组成的新集合。"
  • @john notanumber是正确的-这里不需要detach()。接受的答案是最好的,您只需要正确地阅读文档。
  • Appendto文档还说:"但是,如果有多个目标元素,那么将在第一个元素之后为每个目标创建插入元素的克隆副本,并返回新的集合(原始元素加上克隆)。"因此,在一般情况下,此解决方案还可以创建副本!
  • 伟大的!或者你可以用这个来更具体地说明移动$('#nodeToMove').insertAfter('#insertAfterThisElement');的位置。
  • 我增加了.hide().show(),因为vVertical滚动条出现在我的例子中,我不会:jQuery("#NodesToMove").hide().detach().appendTo('#Destinatio‌​nContainerNode').sho‌​w();
  • 在苦苦挣扎了很长一段时间后,这对我是一个很大的帮助
  • 这是我的首选答案,因为我要将一个元素移动到多个位置-但接受的答案更好地匹配操作问题(=move a to b)。


我刚用过:

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

我从这里抓到的。

  • 好吧,分离在您希望保留元素并稍后重新插入它时很有用,但是在您的示例中,您无论如何都要立即重新插入它。
  • 恐怕我不太明白你在说什么,你能提供示例代码吗?
  • 我的意思是,prependto,从元素的原始位置分离元素,然后在新位置插入元素。另一方面,detach函数只是分离所选元素,您可以将其保存在变量中,以便在以后的某个时间点将其插入到DOM中。问题是,您的分离调用是不必要的。去掉它,你会达到同样的效果。
  • 令人难以置信的是,编辑完全改变了这个答案,一年后又增加了另一个答案(与原来的相同),并获得800多张赞成票…


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

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

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

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

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

1
$("#element").html('...');

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

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

  • 不能在.append()中使用选择器。如果您使用一个字符串作为参数,它将在元素后面附加"other_element"。
  • @菲尔博扎克好吧,是的,我错了:),如果你想自由编辑
  • 我觉得所有的黑体字都有点难读,但这是最有信息的答案,所以它得到了我的支持。


JavaScript解决方案怎么样?

声明片段:

var fragment = document.createDocumentFragment();

将所需元素附加到片段:

fragment.appendChild(document.getElementById('source'));

将片段附加到所需元素:

document.getElementById('destination').appendChild(fragment);

过来看。

  • 为什么使用CreateDocumentFragment而不是简单的document.getElementByID("destination").AppendChild(document.&zwnj;&8203;getElementByID("sour&zwnj;&8203;ce")?
  • @gunarc.gessner假设在将源对象添加到目标对象之前需要修改源对象,那么最好的方法是使用一个虚构的对象片段,该片段不是DOM树的一部分,当源对象从其原始位置(现在它位于片段)而不是在附加它之前在它的初始位置修改它。
  • 为了提供一个JavaScript纯解决方案的相关性,我想添加。不应该假定jquery总是被使用
  • 问题:在附加子节点时,是否丢失附加的事件?
  • 我自己的问题的答案是"是",它保留了所附的事件。


你可以使用:

在后面插入,

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

要插入到另一个元素中,

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


曾经尝试过简单的javascript…EDOCX1?9?

1
onclick = function(){ destination.appendChild(source); }
1
2
3
div{ margin: .1em; }
#destination{ border: solid 1px red; }
#source {border: solid 1px gray; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!DOCTYPE html>
<html>

 <body>

 
   ###
 
 
   ***
 

 </body>
</html>

  • *有人在演示片段的全局事件onclick前面加上关键字var,试图增强帖子,但这是错误的!
  • 人们仍然认为jquery等于javascript,这真是令人惊讶。真的,2017年不再需要jquery了。


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

Move Div in Another Div with jQuery

下面是一个简短的例子:

要在元素上方移动:

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

在元素之后移动:

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

要在某个元素内移动,请执行以下操作:首先在该容器内的所有元素内移动:

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

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

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

可以使用以下代码将源移动到目标

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

尝试工作代码笔

1
2
3
4
5
function move() {
 jQuery("#source")
   .detach()
   .appendTo('#destination');
}
1
2
3
4
5
6
7
8
9
10
11
12
#source{
  background-color:red;
  color: #ffffff;
  display:inline-block;
  padding:35px;
}
#destination{
  background-color:blue;
  color: #ffffff;
  display:inline-block;
  padding:50px;
}
1
2
3
4
5
6
7
8
9
10
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">

I am source



I am destination


<button onclick="move();">Move</button>


这是一个老问题,但我来这里是因为我需要将内容从一个容器移动到另一个容器,包括所有事件侦听器。

jquery没有办法做到这一点,但标准的dom函数appendchild做到了。

1
2
3
//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


您也可以尝试:

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

但这将完全覆盖您在#destination中的所有内容。

  • 并中断已移动元素上的事件侦听器。


我注意到前后插入或前后插入之间存在巨大的内存泄漏和性能差异。如果您有大量的DOM元素,或者需要在mousemove事件中使用after()或before(),则浏览器内存可能会增加,下一个操作将运行得非常慢。我刚刚经历的解决方案是在()之前使用insertbefore,在()之后使用insertafter。

  • 这听起来像是一个与JavaScript引擎实现相关的问题。您使用哪个浏览器版本和JS引擎看到这个?
  • 我使用的是Chrome36.0.1985.125版,使用的是jquery v1.11.1。我在mousemove事件上绑定了一个函数,它将一个简单的DIV向下或向上移动鼠标所在的元素。因此,当拖动光标时,此事件和函数将运行。如果将光标移动30秒以上,则在after()和before()中会发生内存泄漏;如果只使用insertafter&insertbefore,则会消失。
  • 我会用谷歌打开一个bug。


您可以使用纯javascript,使用appendChild()方法…

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.

所以你可以这样做来完成这项工作,这是我为你创建的,使用appendChild(),运行并查看它如何适用于你的案例:

1
2
3
4
function appendIt() {
  var source = document.getElementById("source");
  document.getElementById("destination").appendChild(source);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#source {
  color: white;
  background: green;
  padding: 4px 8px;
}

#destination {
  color: white;
  background: red;
  padding: 4px 8px;
}

button {
  margin-top: 20px;
}
1
2
3
4
5
6
7
8
9
10
11
12
  <p>
Source
</p>



  <p>
Destination
</p>


<button onclick="appendIt()">Move Element</button>


为了完整起见,本文中还提到了另一种方法wrap()wrapAll()。所以OP的问题可以通过这个来解决(也就是说,假设还不存在,下面的方法将从头开始创建这样一个包装器——OP不清楚包装器是否已经存在):

1
2
3
$("#source").wrap('')
// or
$(".source").wrapAll('')

听起来很有希望。但是,当我尝试在这样的多个嵌套结构上执行$("[id^=row]").wrapAll("

")时:

1
2
    <label>Name</label>
    <input ...>

它正确地包装了那些......,但不知何故遗漏了。所以我最终使用了明确的$("row1").append("#a_predefined_fieldset")。所以,YMMV。