Reputation: 1609
Here is my HTML:
<span >I</span>
<span > </span>
<span class="highlight">
<span >l</span>
<span >i</span>
<span >v</span>
<span >e</span>
<span > </span>
</span>
<span >h</span>
<span >e</span>
<span >r</span>
<span >e</span>
I want to remove the element with class ="highlight" and keep its child element. What I did is toRemove.outerHTML = toRemove.innerHTML;
, it works fine, but when I check the updated HTML, it creates empty span element surrounding "live". Is there any way to remove parent element and keep its child element without creating empty span element? Thanks.
UPDATE: Thanks for all your answers. What if I only allow to use pure Javascript, not Jquery to do this?
Upvotes: 1
Views: 420
Reputation: 28722
Use insertAfter to insert the children elements after your wrapping element to maintain the position. Then detach() or remove() the wrapper.
$('#fixit').on('click', function(e) {
var $highlight = $('.highlight');
var $children = $highlight.children();
$children.insertAfter($highlight);
$highlight.remove();
});
body > span {
background-color: gold;
}
.highlight {
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span >I</span>
<span > </span>
<span class="highlight">
<span >l</span>
<span >i</span>
<span >v</span>
<span >e</span>
<span > </span>
</span>
<span >h</span>
<span >e</span>
<span >r</span>
<span >e</span>
<button id="fixit">Fix it</button>
If you use detach() to remove the the element you could store it in a variable to reattach it later if you need to "revert the changes" and keeping a reference to the children as well to add it after again.
+function() {
var $highlight = null;
var $children = null;
$('#fixit').on('click', function(e) {
if($highlight == null) {
$highlight = $('.highlight');
$children = $highlight.children();
$children.insertAfter($highlight);
$highlight.detach();
}
else {
/** get the first child position, otherwise there are four wrappers **/
$highlight.insertAfter($children.first());
$highlight.append($children);
$children = null;
$highlight = null;
}
});
}();
body > span {
background-color: gold;
}
.highlight {
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span >I</span>
<span > </span>
<span class="highlight">
<span >l</span>
<span >i</span>
<span >v</span>
<span >e</span>
<span > </span>
</span>
<span >h</span>
<span >e</span>
<span >r</span>
<span >e</span>
<button id="fixit">Fix it</button>
A pure JS solution as requested in the comments:
var fixit = document.getElementById('fixit');
fixit.addEventListener('click', function(e) {
// get all elements with marker class.
var highlights = document.getElementsByClassName('highlight');
if(highlights.length) {
// iterate them all
for(c = 0; c < highlights.length;c++) {
var highlight = highlights[c];
var children = highlight.children;
// get all the children, last first then add them to parent so order is preserved
for(i = children.length-1; i > -1; i--) {
highlight.parentNode.insertBefore(children[i], highlight.nextSibling);
}
}
// remove the marked elment.
highlight.parentNode.removeChild(highlight);
}
});
body > span {
background-color: gold;
}
.highlight {
background-color: red;
}
<span >I</span>
<span > </span>
<span class="highlight">
<span >l</span>
<span >i</span>
<span >v</span>
<span >e</span>
<span > </span>
</span>
<span >h</span>
<span >e</span>
<span >r</span>
<span >e</span>
<button id="fixit">Fix it</button>
Upvotes: 3
Reputation: 1407
Remove the original after saving a copy of its' children and put the children back after the appropriate element. (Or before or whatever you feel like.)
Demo:
https://jsfiddle.net/xpvt214o/513654/
var highlight = $(".highlight");
var children = highlight.children()
highlight.remove()
$('span').each(function(i,e){
if (i == 1)
$(this).after(children);
});
Upvotes: 0
Reputation: 7368
You can use jQuery's .contents()
to get Get the children of each element , including text and comment nodes.
You can do something like this:
var data = $(".highlight").contents();
$(".highlight").replaceWith(data);
.highlight { background-color:blue }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span >I</span>
<span > </span>
<span class="highlight">
<span >l</span>
<span >i</span>
<span >v</span>
<span >e</span>
<span > </span>
</span>
<span >h</span>
<span >e</span>
<span >r</span>
<span >e</span>
Upvotes: 0
Reputation: 67505
unwrap(): Remove the parents of the set of matched elements from the DOM, leaving the matched elements in their place.
You could simply use the jQuery method .unwrap()
like :
$(toRemove).unwrap();
Upvotes: 0