如何在JavaScript中只删除父元素,而不是它的子元素?

我们说:

<div> some text <div class="remove-just-this"> <p>foo</p> <p>bar</p> some text node here </div> some text </div> 

对此:

 <div> some text <p>foo</p> <p>bar</p> some text node here some text </div> 

我一直在找出使用Mootools,jQuery甚至(原始)JavaScript,但不知道如何做到这一点。

使用jQuery,你可以这样做:

 var cnt = $(".remove-just-this").contents(); $(".remove-just-this").replaceWith(cnt); 

快速链接到文档:

  • 内容 (): jQuery
  • replaceWith ( content :[ String | Element | jQuery ]): jQuery

独立于库的方法是在删除元素之前,先将要删除的元素的所有子节点(隐式地从旧元素中删除它们)插入:

 while (nodeToBeRemoved.firstChild) { nodeToBeRemoved.parentNode.insertBefore(nodeToBeRemoved.firstChild, nodeToBeRemoved); } nodeToBeRemoved.parentNode.removeChild(nodeToBeRemoved); 

这将以正确的顺序将所有子节点移动到正确的位置。

您应该确保使用DOM而不是innerHTML(如果使用由jk提供的jQuery解决scheme,请确保它移动DOM节点,而不是在内部使用innerHTML),以便保留事件处理程序之类的内容。

我的答案很像insin's,但是对于大型结构会更好(单独附加每个节点可能需要在每个appendChild重新应用CSS时重新征税);对于DocumentFragment,这只会发生一次,因为直到在它的孩子都被附加后,它被添加到文档中)。

 var fragment = document.createDocumentFragment(); while(element.firstChild) { fragment.appendChild(element.firstChild); } element.parentNode.replaceChild(fragment, element); 
  $('.remove-just-this > *').unwrap() 

更优雅的方式是

 $('.remove-just-this').contents().unwrap(); 

无论您使用的是哪个库,都必须在从DOM中除去外部div之前克隆内部div。 然后,你必须将克隆的内部div添加到DOM中外部div所在的位置。 所以步骤是:

  1. 在外部variables中保存对外部div的引用
  2. 将内部div复制到另一个variables。 这可以通过将内部div的innerHTML保存为variables来以快速且肮脏的方式完成,或者可以逐个节点地recursion地复制内部树。
  3. 以外部div作为参数,调用外部div的父级上的removeChild
  4. 将复制的内容插入到正确位置的外部div的父项。

有些图书馆会为你做一些或全部的工作,但是像上面这样的内容将会在后台进行。

而且,既然你也尝试过使用mootools,下面是mootools的解决scheme。

 var children = $('remove-just-this').getChildren(); children.replaces($('remove-just-this'); 

请注意,这是完全没有经过testing的,但我以前使用过mootools,它应该工作。

http://mootools.net/docs/Element/Element#Element:getChildren

http://mootools.net/docs/Element/Element#Element:replaces

使用现代的JS!

 const node = document.getElementsByClassName('.remove-just-this')[0]; node.replaceWith(...node.childNodes); // or node.children, if you don't want textNodes 

oldNode.replaceWith(newNode)是有效的ES5

...array是传播运算符,传递每个数组元素作为参数

如果你想用睡衣做同样的事情,那么就是这样做的。 它很好(谢谢眼睑)。 我已经能够做出适当的丰富的文本编辑器,正确地做风格,而不会搞砸,感谢这一点。

 def remove_node(doc, element): """ removes a specific node, adding its children in its place """ fragment = doc.createDocumentFragment() while element.firstChild: fragment.appendChild(element.firstChild) parent = element.parentNode parent.insertBefore(fragment, element) parent.removeChild(element) 

在处理重要的DOM时,我一直在寻找性能最佳的答案。

无睑的答案指出,使用JavaScript的performance将是最好的。

我已经做了5000行以上的执行时间testing,并在要删除的部分内使用了复杂的DOM组合。 使用JavaScript时,为了方便,我使用的是ID而不是类。

使用$ .unwrap()

 $('#remove-just-this').contents().unwrap(); 

201.237ms

使用$ .replaceWith()

 var cnt = $("#remove-just-this").contents(); $("#remove-just-this").replaceWith(cnt); 

156.983ms

在JavaScript中使用DocumentFragment

 var element = document.getElementById('remove-just-this'); var fragment = document.createDocumentFragment(); while(element.firstChild) { fragment.appendChild(element.firstChild); } element.parentNode.replaceChild(fragment, element); 

147.211ms

结论

在性能方面,即使在相对较大的DOM结构上,使用jQuery和JavaScript的差异也不是很大。 令人惊讶的$.unwrap()是最昂贵的$.replaceWith() 。 testing已经用jQuery 1.12.4完成了。

如果你正在处理多行,就像在我的用例中那样,你可能会更好地使用这些行:

  $(".card_row").each(function(){ var cnt = $(this).contents(); $(this).replaceWith(cnt); });