97

比方说:

<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,但不知道如何做到这一点。

4

12 回答 12

142

使用jQuery你可以这样做:

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

文档的快速链接:

  • 内容():jQuery
  • 替换内容:[字符串|元素| jQuery ]):jQuery
于 2008-10-04T09:37:35.073 回答
36

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

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

nodeToBeRemoved.parentNode.removeChild(nodeToBeRemoved);

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

于 2008-10-04T12:11:36.527 回答
35

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

我的答案很像 insin 的,但对于大型结构会表现更好(单独附加每个节点可能会对重绘产生负担,其中必须为每个节点重新应用 CSS appendChild;使用 a DocumentFragment,这只会发生一次,因为它直到它之后才可见孩子都被附加,它被添加到文档中)。

var fragment = document.createDocumentFragment();
while(element.firstChild) {
    fragment.appendChild(element.firstChild);
}
element.parentNode.replaceChild(fragment, element);
于 2008-10-06T22:07:00.533 回答
30
 $('.remove-just-this > *').unwrap()
于 2011-10-19T13:55:19.220 回答
25

更优雅的方式是

$('.remove-just-this').contents().unwrap();
于 2016-04-01T16:22:00.603 回答
14

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

于 2017-08-13T18:56:29.577 回答
6

将 div 替换为其内容:

const wrapper = document.querySelector('.remove-just-this');
wrapper.outerHTML = wrapper.innerHTML;
<div>
  pre text
  <div class="remove-just-this">
    <p>child foo</p>
    <p>child bar</p>
    nested text
  </div>
  post text
</div>

于 2019-03-11T13:54:07.293 回答
2

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

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

一些图书馆会为你做部分或全部,但类似上面的事情会在幕后发生。

于 2008-10-04T11:06:24.923 回答
2

而且,由于您也尝试过 mootools,因此这里是 mootools 中的解决方案。

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

请注意,这完全未经测试,但我之前使用过 mootools,它应该可以工作。

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

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

于 2008-10-22T21:30:13.130 回答
1

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

eyelidlessness 的回答是指出使用 javascript 的性能是最好的。

我已经对 5,000 行和 400,000 个字符进行了以下执行时间测试,其中要删除的部分内部具有复杂的 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 完成的。

于 2017-02-17T13:14:49.207 回答
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)
于 2012-04-24T11:57:45.450 回答
0

如果您正在处理多行,就像在我的用例中那样,您可能最好使用以下几行:

 $(".card_row").each(function(){
        var cnt = $(this).contents();
        $(this).replaceWith(cnt);
    });
于 2017-05-15T12:11:36.993 回答