如何使用JavaScript将所有HTML元素子元素移动到另一个父元素?
想象一下:如何使用JavaScript将所有HTML元素子元素移动到另一个父元素?,javascript,html,dom-manipulation,Javascript,Html,Dom Manipulation,想象一下: <div id="old-parent"> <span>Foo</span> <b>Bar</b> Hello World </div> <div id="new-parent"></div> 这是一个拟议的重复问题的答案将导致: <div id="new-parent"> <div id="old-parent">
<div id="old-parent">
<span>Foo</span>
<b>Bar</b>
Hello World
</div>
<div id="new-parent"></div>
这是一个拟议的重复问题的答案将导致:
<div id="new-parent">
<div id="old-parent">
<span>Foo</span>
<b>Bar</b>
Hello World
</div>
</div>
福
酒吧
你好,世界
这里有一个简单的函数:
function setParent(el, newParent)
{
newParent.appendChild(el);
}
el
的childNodes
是要移动的元素,newParent
是将要移动到的元素el
,因此您可以执行如下功能:
var l = document.getElementById('old-parent').childNodes.length;
var a = document.getElementById('old-parent');
var b = document.getElementById('new-parent');
for (var i = l; i >= 0; i--)
{
setParent(a.childNodes[0], b);
}
只有当您不需要执行任何操作,只需要将内部代码(innerHTML)从一个传输到另一个时,此答案才真正有效:
// Define old parent
var oldParent = document.getElementById('old-parent');
// Define new parent
var newParent = document.getElementById('new-parent');
// Basically takes the inner code of the old, and places it into the new one
newParent.innerHTML = oldParent.innerHTML;
// Delete / Clear the innerHTML / code of the old Parent
oldParent.innerHTML = '';
希望这有帮助
基本上,您希望循环遍历旧父节点的每个直接子节点,并将其移动到新父节点。任何直系后裔的孩子都会被它感动
var newParent = document.getElementById('new-parent');
var oldParent = document.getElementById('old-parent');
while (oldParent.childNodes.length > 0) {
newParent.appendChild(oldParent.childNodes[0]);
}
如果在id的名称中未使用
-
,则可以执行此操作
oldParent.id='xxx';
newParent.id='oldParent';
xxx.id='newParent';
oldParent.parentNode.insertBefore(oldParent,newParent)代码>
#newParent{color:red}
福
酒吧
你好,世界
现代方式:
newParent.append(…oldParent.childNodes);
.append
是.appendChild
的替代品。主要区别在于它一次接受多个节点,甚至接受普通字符串,如.append('hello!')
oldParent.childNodes
是可编辑的,因此它可以与..
一起传播,成为.append()的多个参数
两者的兼容性表(简而言之:Edge 17+,Safari 10+):
可能重复@MarcB,这不是重复。您链接到的问题并不涉及移动所有子节点,该问题的任何答案也不能满足我移动不同类型HTML节点(例如文本节点)的需要。答案正是您所需要的。dom是一棵树。移动一个节点,该节点的所有子节点都将随之移动。@MarcB有时您不希望目标中有父对象。例如,将一个待办事项列表的所有元素从“未决”到“完整”的父元素移动。您将如何使用他的代码?如果将旧父元素作为el
传递,这也将移动该元素。这将导致HTML:…
也无法工作,因为移动子元素时,长度会发生变化。因此,最终只能移动一半的节点。你需要向后迭代,或者像我一样使用while循环。仍然不起作用。您需要执行:for(var i=l;i>=0;i--)
或while(document.getElementById('old-parent')。length>0)
。另外,您的演示中也有错误。@查看编辑,sry-while(document.getElementById('old-parent').length>0){setParent(document.getElementById('old-parent')[i],document.getElementById('new-parent');}
这很有效,尽管我并不想通过HTML字符串进行序列化/反序列化。但它确实可以工作:)它不会复制任何附加到元素的对象和事件此重新生成DOM,它不会移动现有的节点/事件,并且可能比所有孩子上的循环慢得多。我运行了一些简单的测试,此方法仍然比公认的答案慢,如前所述,它也有缺点。为了真正有效:while(oldParent.childNodes.length){newParent.appendChild(oldParent.firstChild);}
注意,childNodes[]通常也包含空文本节点(源代码中的每一行都有一个)@Gibolt我创建了一个测试,它似乎向我表明数组访问比调用firstChild
更快。这种差别充其量也可以忽略不计。它可能也会因浏览器而异。不过,我认为firstChild
更具可读性代码>和while(oldParent.firstChild)newParent.appendChild(oldParent.firstChild)代码>在Chromium中工作快2倍,在Firefox中工作快6到10倍。如果您在追求性能,那么使用DocumentFragment并同时移动所有元素可能是有益的。看起来非常优雅。我想知道这里的其他答案是否有性能上的差异。如果有,它必须是最小的。如果有什么不同的话,它会更快,因为它是一个append
调用,而不是很多调用。请注意:对于IE11(可能永远不会)不是很好,但我做了一些简单的测试,并且while()
在Chrome中仍然稍微快一点。不要相信我的话,如果可能的话,进行你自己的测试。
var newParent = document.getElementById('new-parent');
var oldParent = document.getElementById('old-parent');
while (oldParent.childNodes.length > 0) {
newParent.appendChild(oldParent.childNodes[0]);
}