如何在JavaScript中仅删除父元素而不删除其子元素?


88

比方说:

<div>
  pre text
  <div class="remove-just-this">
    <p>child foo</p>
    <p>child bar</p>
    nested text
  </div>
  post text
</div>

对此:

<div>
  pre text
  <p>child foo</p>
  <p>child bar</p>
  nested text
  post text
</div>

我一直在寻找使用Mootools,jQuery甚至是(原始)JavaScript的方法,但是却不知道该怎么做。

Answers:


138

使用jQuery,您可以执行以下操作:

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

快速链接到文档:

  • 内容():jQuery
  • replaceWith内容:[ 字符串 | 元素 | jQuery ]):jQuery

希望我 3个小时前意识到(发现)……简单而优雅-太棒了!
Tathagata

3
“ cnt”的意义是什么?
史蒂文·卢

1
“ cnt”只是一个包含“内容”的变量名
George Anderson

1
我不确定为什么,但这在使用contents()时对我不起作用。但是,当我使用html()代替content()时,它就像一个魅力!
vertigoelectric 2012年

仅有1行版本:$('.remove-just-this').replaceWith(function() { return $(this).html(); });
Taufik Nur Ra​​hmanda '17

36

与库无关的方法是,在删除元素之前,先将要删除的元素的所有子节点插入自身(从原位置隐式删除它们):

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

nodeToBeRemoved.parentNode.removeChild(nodeToBeRemoved);

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


3
现代JS支持这一点:node.replaceWith(...node.childNodes);
Gibolt

34

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

我的答案很像insin的答案,但是对于大型结构而言,它的性能会更好(单独添加每个节点可能会对必须为每个CSS重新应用CSS的重绘加税appendChild;使用DocumentFragment,这只会发生一次,因为直到它被显示之后才可见子项均已附加,并将其添加到文档中)。

var fragment = document.createDocumentFragment();
while(element.firstChild) {
    fragment.appendChild(element.firstChild);
}
element.parentNode.replaceChild(fragment, element);

谢谢; 简短而直接。
brunoais



7

使用现代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 是散布运算符,将每个数组元素作为参数传递


2

无论使用哪个库,都必须先克隆内部div,然后再从DOM中删除外部div。然后,您必须将克隆的内部div添加到DOM中外部div所在的位置。因此,步骤如下:

  1. 将对外部div的父级的引用保存在变量中
  2. 将内部div复制到另一个变量。可以通过innerHTML将内部div的in保存到变量中来快速而又肮脏地完成此操作,也可以逐个节点递归地复制内部树。
  3. removeChild以外部div为参数调用外部div的父对象。
  4. 将复制的内部内容插入正确位置的外部div的父级。

有些图书馆会为您完成部分或全部这些工作,但是类似上面的事情将在后台进行。




0

如果您想在睡衣上做同样的事情,请按以下步骤操作。它的效果很好(感谢您的眼睑)。由于这一点,我已经能够制作一个适当的富文本编辑器,该编辑器可以正确地执行样式而不会造成混乱。

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)

1
这是哪一种语言?
brunoais 2015年

看起来像python-自用户提及以来就很有意义pyjamas
mgilson

0

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

眼睑失明的答案指出,使用javascript效果最佳。

我对要删除的5,000行和40万个字符进行了以下执行时间测试,并在其中添加了复杂的DOM组成。出于方便原因,在使用javascript时,我使用的是ID而不是类。

使用$ .unwrap()

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

201.237毫秒

使用$ .replaceWith()

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

156.983毫秒

在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.211毫秒

结论

在性能方面,即使在相对较大的DOM结构上,使用jQuery和javascript之间的差异也不是很大。出人意料的$.unwrap()是比$.replaceWith()。测试已使用jQuery 1.12.4完成。


0

如果您要处理多行,就像在我的用例中那样,那么最好遵循以下几行:

 $(".card_row").each(function(){
        var cnt = $(this).contents();
        $(this).replaceWith(cnt);
    });
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.