[英]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:
所以步骤是:
innerHTML
of the inner div to a variable or you can copy the inner tree recursively node by node. innerHTML
保存到变量以快速而脏的方式完成,或者可以逐个节点地递归复制内部树。 removeChild
on the outer div's parent with the outer div as the argument. removeChild
。 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.