How to remove only the source element and not its children in JavaScript?
Say:
<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> I found out using Mootools, jQuery, and even (raw) JavaScript, but couldn't figure out how to do this.
Using jQuery , you can do this:
var cnt = $(".remove-just-this").contents(); $(".remove-just-this").replaceWith(cnt); Quick links to documentation:
- contents (): jQuery
- replaceWith (contents: [String | Element | jQuery]): jQuery
A library-independent method is to insert all the child nodes of the element that you want to remove in front of you (which implicitly removes them from their previous position) before you delete it:
while (nodeToBeRemoved.firstChild) { nodeToBeRemoved.parentNode.insertBefore(nodeToBeRemoved.firstChild, nodeToBeRemoved); } nodeToBeRemoved.parentNode.removeChild(nodeToBeRemoved); This will move all the child nodes to the right place in the correct order.
You should do this using the DOM, not innerHTML (and if you are using the jQuery solution provided by jk, make sure it moves the DOM nodes and not internally innerHTML) to preserve such as event handlers.
My answer is very similar to insin's, but it will work better for large structures (adding each node separately can be taxed on redraws where CSS has to be reapplied for each appendChild; with DocumentFragment this only happens once until it is displayed until its children will not be added and added to the document).
var fragment = document.createDocumentFragment(); while(element.firstChild) { fragment.appendChild(element.firstChild); } element.parentNode.replaceChild(fragment, element); $('.remove-just-this > *').unwrap() More elegant way
$('.remove-just-this').contents().unwrap(); Whatever library you use, you need to clone the inner div before removing the outer div from the DOM. Then you need to add the cloned inner div to the location in the DOM where the outer div was. So the steps are:
- Save link to external parent div in variable
- Copy the inner div to another variable. This can be done in a quick and dirty way by storing the
innerHTMLinner div in a variable, or you can copy the inner tree recursively from node to node. - Call
removeChildon the outer div parent with the outer div as an argument. - Paste the copied inner content into the outer parent div in the correct position.
Some libraries will do some or all of this for you, but something like the above will happen under the hood.
And since you tried in mootools too, here is the solution in mootools.
var children = $('remove-just-this').getChildren(); children.replaces($('remove-just-this'); Please note that it is completely untested, but I have worked with mootools before and it should work.
http://mootools.net/docs/Element/Element#Element:getChildren
Use modern 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) really ES5
...array is a spreading operator that passes each element of the array as a parameter
if you want to do the same in pajamas, here's how to do it. it works great (thanks a century). I was able to create a proper text editor, which, in fact, makes styles without ruining, 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 performance answer while working on an important DOM.
The answer to the question that using javascript would be best would be better.I performed the following run time tests on 5,000 lines and 400,000 characters with a composite DOM composition inside a section for deletion. I use ID instead of class for convenience when using javascript.
Using $ .unwrap ()
$('#remove-just-this').contents().unwrap(); 201.237ms
Using $ .replaceWith ()
var cnt = $("#remove-just-this").contents(); $("#remove-just-this").replaceWith(cnt); 156.983ms
Using DocumentFragment in javascript
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
Conclusion
Performance, even with a relatively large DOM structure, the difference between using jQuery and javascript is small. Amazingly, $.unwrap() is more expensive than $.replaceWith() . Tests were performed using jQuery 1.12.4.
If you are dealing with multiple lines, as was the case in my use case, you are probably best off doing something on these lines:
$(".card_row").each(function(){ var cnt = $(this).contents(); $(this).replaceWith(cnt); });