2008-10-04 57 views
76

比方说:如何在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,但不能得到的想法如何做到这一点。

回答

122

使用jQuery你可以这样做:

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

快速链接到文件:

  • contents():jQuery的
  • replaceWith内容字符串 | Elemen t | jQuery的):jQuery的
+0

更清洁溶液比我! – ConroyP 2008-10-04 09:42:24

+0

希望我意识到(错误.. **发现**)这3小时前...简单而优雅 - 真棒! – Tathagata 2011-06-01 21:10:59

+2

'cnt'的意义是什么? – 2011-09-25 23:12:42

2

无论图书馆使用的是你必须从DOM移除外层div之前克隆内股利。然后,您必须将克隆的内部div添加到外部div所在DOM的位置。因此,步骤是:

  1. 在一个变量
  2. 副本内的div保存到外部div的父级的引用到另一个变量。这可以通过将内部div的innerHTML保存为变量来以快速且肮脏的方式完成,或者您可以逐节点复制内部树。
  3. 拨打removeChild将外部div的父母与外部div作为参数。
  4. 将复制的内容插入正确位置的外部div的父项。

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

34

库无关的方法是插入元素的所有子节点被自己之前(这隐式地从自己的老位置删除它们)删除,可以将其取出:

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

nodeToBeRemoved.parentNode.removeChild(nodeToBeRemoved); 

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

31

您应该确保使用DOM而不是innerHTML(如果使用jk提供的jQuery解决方案,请确保它移动DOM节点而不是在内部使用innerHTML),以便保留事件,如事件处理程序。我的答案很像insin's,但对于大型结构会更好(每个appendChild需要重新应用CSS);对于一个DocumentFragment,这只会发生一次,因为它是直到它的孩子都被追加并且被添加到文档中之后才显示)。

var fragment = document.createDocumentFragment(); 
while(element.firstChild) { 
    fragment.appendChild(element.firstChild); 
} 
element.parentNode.replaceChild(fragment, element); 
22
$('.remove-just-this > *').unwrap() 
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) 
12

更优雅的方式是

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

我一直在寻找最好的答案性能明智,同时在重要的DOM工作。

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

我已经对5,000行和400,000个字符进行了以下执行时间测试,并在要删除的部分中使用复杂的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()更昂贵。 测试已经用jQuery 1.12.4完成。

0

如果你正在处理多行,因为它是在我的使用情况,你有东西沿着这些线路可能会更好过:

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

运用现代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是传播算子,通过每个数组元素作为参数