简体   繁体   English

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

[英]How to remove only the parent element and not its child elements in JavaScript?

Let's say: 让我们说:

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

to this: 对此:

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

I've been figuring out using Mootools, jQuery and even (raw) JavaScript, but couldn't get the idea how to do this. 我一直在想使用Mootools,jQuery甚至(原始)JavaScript,但无法理解如何做到这一点。

Using jQuery you can do this: 使用jQuery你可以这样做:

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

Quick links to the documentation: 快速链接到文档:

The library-independent method is to insert all child nodes of the element to be removed before itself (which implicitly removes them from their old position), before you remove it: 与库无关的方法是在删除之前插入要在其自身之前删除的元素的所有子节点(隐式地将它们从旧位置移除):

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

nodeToBeRemoved.parentNode.removeChild(nodeToBeRemoved);

This will move all child nodes to the correct place in the right order. 这将以正确的顺序将所有子节点移动到正确的位置。

You should make sure to do this with the DOM, not innerHTML (and if using the jQuery solution provided by jk, make sure that it moves the DOM nodes rather than using innerHTML internally), in order to preserve things like event handlers. 你应该确保使用DOM,而不是innerHTML (如果使用jk提供的jQuery解决方案,确保它移动DOM节点而不是内部使用innerHTML ),以保留事件处理程序之类的东西。

My answer is a lot like insin's, but will perform better for large structures (appending each node separately can be taxing on redraws where CSS has to be reapplied for each appendChild ; with a DocumentFragment , this only occurs once as it is not made visible until after its children are all appended and it is added to the document). 我的答案很像insin,但是对于大型结构会表现得更好(单独添加每个节点可能会对重新绘制每个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();

Use modern JS! 使用现代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) is valid ES5 oldNode.replaceWith(newNode)是有效的ES5

...array is the spread operator, passing each array element as a parameter ...array是扩展运算符,将每个数组元素作为参数传递

Whichever library you are using you have to clone the inner div before removing the outer div from the DOM. 无论您使用哪个库,都必须在从DOM中删除外部div之前克隆内部div。 Then you have to add the cloned inner div to the place in the DOM where the outer div was. 然后你必须将克隆的内部div添加到外部div所在的DOM中的位置。 So the steps are: 所以步骤是:

  1. Save a reference to the outer div's parent in a variable 在变量中保存对外部div的父级的引用
  2. Copy the inner div to another variable. 将内部div复制到另一个变量。 This can be done in a quick and dirty way by saving the innerHTML of the inner div to a variable or you can copy the inner tree recursively node by node. 这可以通过将内部div的innerHTML保存到变量以快速而脏的方式完成,或者可以逐个节点地递归复制内部树。
  3. Call removeChild on the outer div's parent with the outer div as the argument. 使用外部div作为参数调用外部div的父级上的removeChild
  4. Insert the copied inner content to the outer div's parent in the correct position. 将复制的内部内容插入到外部div的父级中的正确位置。

Some libraries will do some or all of this for you but something like the above will be going on under the hood. 有些图书馆会为你做一些或所有这些,但上面的内容将在幕后进行。

And, since you tried in mootools as well, here's the solution in mootools. 而且,既然你也尝试过mootools,这就是mootools的解决方案。

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

Note that's totally untested, but I have worked with mootools before and it should work. 请注意,这是完全未经测试的,但我之前使用的是mootools,它应该可以工作。

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

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

if you'd like to do this same thing in pyjamas, here's how it's done. 如果你想穿着睡衣做同样的事情,这就是它的完成方式。 it works great (thank you to eyelidness). 它很棒(谢谢你的眼皮)。 i've been able to make a proper rich text editor which properly does styles without messing up, thanks to this. 由于这个原因,我已经能够制作一个适当的富文本编辑器,可以正确地完成样式而不会搞乱。

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)

I was looking for the best answer performance-wise while working on an important DOM. 在处理重要的DOM时,我一直在寻找性能最佳的答案。

eyelidlessness's answer was pointing out that using javascript the performances would be best. eyelidlessness的答案指出,使用javascript,表演将是最好的。

I've made the following execution time tests on 5,000 lines and 400,000 characters with a complexe DOM composition inside the section to remove. 我已经在5,000行和400,000个字符上进行了以下执行时间测试,其中要删除的部分中有复杂的DOM组合。 I'm using an ID instead of a class for convenient reason when using javascript. 我在使用javascript时出于方便的原因使用ID而不是类。

Using $.unwrap() 使用$ .unwrap()

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

201.237ms 201.237ms

Using $.replaceWith() 使用$ .replaceWith()

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

156.983ms 156.983ms

Using DocumentFragment in javascript 在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 147.211ms

Conclusion 结论

Performance-wise, even on a relatively big DOM structure, the difference between using jQuery and javascript is not huge. 性能方面,即使在相对较大的DOM结构上,使用jQuery和javascript之间的差异并不大。 Surprisingly $.unwrap() is most costly than $.replaceWith() . 令人惊讶的是, $.unwrap()$.replaceWith()成本更高。 The tests have been done with jQuery 1.12.4. 测试已经使用jQuery 1.12.4完成。

If you are dealing with multiple rows, as it was in my use case you are probably better off with something along these lines: 如果你正在处理多行,就像在我的用例中那样,你可能会更喜欢这些行:

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

Replace div with its contents: 将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> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何从父元素中删除事件,并仅为其特定的子元素启用该事件? - how to remove an event from a parent element and only enable that event for its particular child element? 如何删除父元素并保留其子元素而不创建空跨度 - How to remove parent element and keep its child elements without creating empty span 如何仅显示父级和子级元素? Java脚本 - How to show only Parent and Child element? Javascript jQuery 将子元素的子节元素移动到其父元素并移除其他元素 - jQuery move child's child section element to its parent and remove other elements 仅当子元素存在于父元素下时,如何才能删除它? - How can I remove a child element only if it exists under a parent? Javascript - 从数组中删除子元素或父元素 - Javascript - remove child or parent elements from an array 在jQuery中仅删除父元素而不删除其子元素 - remove only parent element not its childs in jquery javascript:仅在父元素处于活动状态且子元素具有特定类的情况下,才如何向子元素添加属性? - javascript: how to add an attribute to a child element ONLY if a parent element is active AND child element has a certain class? 如何使用纯Javascript通过其父ID元素按ID获得子元素 - How to get a child element by id by its parent id element using pure Javascript 如何在JavaScript中查找其父级的子位置 - How to find child position of its parent in JavaScript
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM