代码之家  ›  专栏  ›  技术社区  ›  cheeaun

如何在javascript中只删除父元素而不删除子元素?

  •  80
  • cheeaun  · 技术社区  · 17 年前

    让我们说:

    <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>
    

    我一直在考虑使用moooltools、jquery甚至是(原始)javascript,但我不知道如何做到这一点。

    11 回复  |  直到 7 年前
        1
  •  127
  •   Jonathan Mayhak    12 年前

    使用 jQuery 您可以这样做:

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

    文档的快速链接:

        2
  •  35
  •   Jonny Buchanan    17 年前

    与库无关的方法是在移除元素之前,将要移除元素的所有子节点插入到其自身之前(这会隐式地将它们从旧位置移除):

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

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

        3
  •  31
  •   Aliaksandr Sushkevich    8 年前

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

    我的答案很像insin的,但对于大型结构来说会更好(单独附加每个节点可以在重绘时征税,在重绘时必须为每个节点重新应用css appendChild 带着 DocumentFragment ,这只会发生一次,因为只有在其子级全部附加并添加到文档中之后,才能使其可见。

    var fragment = document.createDocumentFragment();
    while(element.firstChild) {
        fragment.appendChild(element.firstChild);
    }
    element.parentNode.replaceChild(fragment, element);
    
        4
  •  25
  •   campino2k    14 年前
     $('.remove-just-this > *').unwrap()
    
        5
  •  16
  •   yunda    10 年前

    更优雅的方式是

    $('.remove-just-this').contents().unwrap();
    
        6
  •  4
  •   Gibolt    8 年前

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

        7
  •  2
  •   domgblackwell    17 年前

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

    1. 在变量中保存对外部DIV父级的引用
    2. 将内部DIV复制到另一个变量。这可以通过保存 innerHTML 将内部DIV复制到变量,或者可以逐节点递归地复制内部树。
    3. 呼叫 removeChild 在外部DIV的父级上,外部DIV作为参数。
    4. 将复制的内部内容插入到外部DIV的父级中的正确位置。

    有些图书馆会为你做一些或者全部的事情,但是像上面这样的事情会发生在你的引擎盖下。

        8
  •  2
  •   TJ L    17 年前

    既然你也尝试过moootools,这里是moootools的解决方案。

    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

        9
  •  0
  •   user362834    14 年前

    如果你想穿睡衣做同样的事情,这里是怎么做的。它很管用(谢谢你的眼皮)。多亏了这一点,我已经能够制作出一个适当的富文本编辑器,它可以正确地处理样式而不会弄乱。

    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)
    
        10
  •  0
  •   maxime_039    9 年前

    我在找最好的答案 性能方面 在处理重要的DOM时。

    眼睑松弛的答案是指出使用javascript的性能最好。

    我已经对5000行和400000个字符进行了以下执行时间测试,在要删除的部分中包含一个复杂的DOM组合。在使用JavaScript时,为了方便起见,我使用的是ID而不是类。

    使用$.Unwrap())

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

    201.23 7MS

    使用$.replaceWith()。

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

    156983MS

    在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完成。

        11
  •  0
  •   LaurensVijnck    9 年前

    如果您处理的是多行,就像我的用例中那样,您可能更擅长处理这些行中的某些内容:

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