Remove a HTML tag but keep the innerHtml

Jquery

Jquery Problem Overview


I have some simple HTML which I need to strip simple formatting.

A nice house was found in <b>Toronto</b>.

I need to remove the bold, but leave the sentence intact.

How is this possible in jQuery?

Jquery Solutions


Solution 1 - Jquery

$('b').contents().unwrap();

This selects all <b> elements, then uses .contents() to target the text content of the <b>, then .unwrap() to remove its parent <b> element.


For the greatest performance, always go native:

var b = document.getElementsByTagName('b');

while(b.length) {
    var parent = b[ 0 ].parentNode;
    while( b[ 0 ].firstChild ) {
        parent.insertBefore(  b[ 0 ].firstChild, b[ 0 ] );
    }
     parent.removeChild( b[ 0 ] );
}

This will be much faster than any jQuery solution provided here.

Solution 2 - Jquery

You can also use .replaceWith(), like this:

$("b").replaceWith(function() { return $(this).contents(); });

Or if you know it's just a string:

$("b").replaceWith(function() { return this.innerHTML; });

This can make a big difference if you're unwrapping a lot of elements since either approach above is significantly faster than the cost of .unwrap().

Solution 3 - Jquery

The simplest way to remove inner html elements and return only text would the JQuery .text() function.

Example:

var text = $('<p>A nice house was found in <b>Toronto</b></p>');

alert( text.html() );
//Outputs A nice house was found in <b>Toronto</b>

alert( text.text() );
////Outputs A nice house was found in Toronto

jsFiddle Demo

Solution 4 - Jquery

Behold, for the simplest answer is mind blowing:

outerHTML is supported down to Internet Explorer 4 !

Here is to do it with javascript even without jQuery

element.outerHTML = element.innerHTML

with jQuery

var element = $('b')[0];
element.outerHTML = element.innerHTML;

or without jQuery

var element = document.querySelector('b');
element.outerHTML = element.innerHTML

If you want it as a function:

function unwrap(selector) {
    var nodelist = document.querySelectorAll(selector);
    Array.prototype.forEach.call(nodelist, function(item,i){
        item.outerHTML = item.innerHTML; // or item.innerText if you want to remove all inner html tags 
    })
}

unwrap('b')

This should work in all major browser including old IE.

If you get NoModificationAllowedError or DOMException, it means the element has no parent. Usually you get this when you're trying this answer by creating a new node from javascript console without putting it as other element's child. But don't worry and remember that any element in the document is at least has one parent (<html></html> element)


NOTE:

this rewrite the innerHTML, so if you have a variable referencing to the inner element, it will not point to the same element.

If you need to keep the reference of some of the inner elements in your coding, you can use the jQuery (top answer) which move the elements to the expected position without rewriting the element.

Solution 5 - Jquery

How about this?

$("b").insertAdjacentHTML("afterend",$("b").innerHTML);
$("b").parentNode.removeChild($("b"));

The first line copies the HTML contents of the b tag to the location directly after the b tag, and then the second line removes the b tag from the DOM, leaving only its copied contents.

I normally wrap this into a function to make it easier to use:

function removeElementTags(element) {
   element.insertAdjacentHTML("afterend",element.innerHTML);
   element.parentNode.removeChild(element);
}

All of the code is actually pure Javascript, the only JQuery being used is that to select the element to target (the b tag in the first example). The function is just pure JS :D

Also look at:

Solution 6 - Jquery

// For MSIE:
el.removeNode(false);

// Old js, w/o loops, using DocumentFragment:
function replaceWithContents (el) {
  if (el.parentElement) {
    if (el.childNodes.length) {
      var range = document.createRange();
      range.selectNodeContents(el);
      el.parentNode.replaceChild(range.extractContents(), el);
    } else {
      el.parentNode.removeChild(el);
    }
  }
}

// Modern es:
const replaceWithContents = (el) => {
  el.replaceWith(...el.childNodes);
};

// or just:
el.replaceWith(...el.childNodes);

// Today (2018) destructuring assignment works a little slower
// Modern es, using DocumentFragment.
// It may be faster than using ...rest
const replaceWithContents = (el) => {
  if (el.parentElement) {
    if (el.childNodes.length) {
      const range = document.createRange();
      range.selectNodeContents(el);
      el.replaceWith(range.extractContents());
    } else {
      el.remove();
    }
  }
};

Solution 7 - Jquery

Another native solution (in coffee):

el = document.getElementsByTagName 'b'

docFrag = document.createDocumentFragment()
docFrag.appendChild el.firstChild while el.childNodes.length

el.parentNode.replaceChild docFrag, el

I don't know if it's faster than user113716's solution, but it might be easier to understand for some.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionIan VinkView Question on Stackoverflow
Solution 1 - Jqueryuser113716View Answer on Stackoverflow
Solution 2 - JqueryNick CraverView Answer on Stackoverflow
Solution 3 - JqueryWebChemistView Answer on Stackoverflow
Solution 4 - JqueryizzulmakinView Answer on Stackoverflow
Solution 5 - JqueryToastrackenigmaView Answer on Stackoverflow
Solution 6 - JqueryrediskoView Answer on Stackoverflow
Solution 7 - JqueryGijsjanBView Answer on Stackoverflow