Jon
Jon

Reputation: 8521

JS - Remove a tag without deleting content

I am wondering if it is possible to remove a tag but leave the content in tact? For example, is it possible to remove the SPAN tag but leave SPAN's content there?

<p>The weather is sure <span>sunny</span> today</p> //original

<p>The weather is sure sunny today</p> //turn it into this

I have tried using this method of using replaceWith(), but it it turned the HTML into

<p>
  "The weather is sure " 
  "sunny"
  " today"
</p>

EDIT : After testing all of your answers, I realized that my code is at fault. The reason why I keep getting three split text nodes is due to the insertion of the SPAN tag. I'll create another question to try to fix my problem.

Upvotes: 16

Views: 11364

Answers (9)

thomas
thomas

Reputation: 915

You can remove the span element and keep the HTML content or internal text intact. With jQuery’s unwrap() method.

    <html>
      <head>
        <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
        <script type="text/javascript">
          $(document).ready(function(){
            $("button").click(function(){
              $("p").find("span").contents().unwrap();
            });
          });
        </script>
      </head>
      <body>
        <p>The weather is sure <span style="background-color:blue">sunny</span> today</p>
        <button type="button">Remove span</button>
      </body>
    </html>

You can see an example here: How to remove a tag without deleting its content with jQuery

Upvotes: 0

KittMedia
KittMedia

Reputation: 7466

If it’s the only child span inside the parent, you could do something like this:

HTML:

<p class="parent">The weather is sure <span>sunny</span> today</p>;

JavaScript:

parent = document.querySelector('.parent');
parent.innerHTML = parent.innerText;

So just replace the HTML of the element with its text.

Upvotes: 0

Andrea
Andrea

Reputation: 326

If someone is still looking for that, the complete solution that has worked for me is:

Assuming we have:

<p>hello this is the <span class="highlight">text to unwrap</span></p>

the js is:

// get the parent
var parentElem = $(".highlight").parent(); 

// replacing with the same contents
$(".highlight").replaceWith( 
    function() { 
        return $(this).contents();
    }
);

// normalize parent to strip extra text nodes
parentElem.each(function(element,index){
    $(this)[0].normalize();
});

Upvotes: 0

dmbania
dmbania

Reputation: 41

If you're not looking for a jQuery solution, here something that's a little more lightweight and focused on your scenario.

I created a function called getText() and I used it recursively. In short, you can get the child nodes of your p element and retrieve all the text nodes within that p node.

Just about everything in the DOM is a node of some sort. Looking up at the following links I found that text nodes have a numerical nodeType value of 3, and when you identify where your text nodes are, you get their nodeValueand return it to be concatenated to the entire, non-text-node-free value.

https://developer.mozilla.org/en/nodeType

https://developer.mozilla.org/En/DOM/Node.nodeValue

var para = document.getElementById('p1')  // get your paragraphe 
var texttext = getText(para);             // pass the paragraph to the function
para.innerHTML = texttext                 // set the paragraph with the new text

function getText(pNode) {

    if (pNode.nodeType == 3) return pNode.nodeValue;

    var pNodes = pNode.childNodes        // get the child nodes of the passed element
    var nLen = pNodes.length             // count how many there are
    var text = "";

    for (var idx=0; idx < nLen; idx++) {   // loop through the child nodes
        if (pNodes[idx].nodeType != 3 ) {  // if the child not isn't a text node
            text += getText(pNodes[idx]);  // pass it to the function again and 
                                           // concatenate it's value to your text string  
        } else {
            text += pNodes[idx].nodeValue  // otherwise concatenate the value of the text
                                           // to the entire text
        }

    }

    return text
}

I haven't tested this for all scenarios, but it will do for what you're doing at the moment. It's a little more complex than a replace string since you're looking for the text node and not hardcoding to remove specific tags.

Good Luck.

Upvotes: 0

user1106995
user1106995

Reputation: 800

jQuery has easier ways:

var spans = $('span');
spans.contents().unwrap();

With different selector methods, it is possible to remove deeply nested spans or just direct children spans of an element.

Upvotes: 7

kennebec
kennebec

Reputation: 104770

<p>The weather is sure <span>sunny</span> today</p>;


var span=document.getElementsByTagName('span')[0]; // get the span
var pa=span.parentNode;
while(span.firstChild) pa.insertBefore(span.firstChild, span);

pa.removeChild(span);

Upvotes: 14

Chris Visser
Chris Visser

Reputation: 1647

There are several ways to do it. Jquery is the most easy way:

//grab and store inner span html
var content = $('p span').html;
//"Re"set inner p html
$('p').html(content);

Javascript can do the same using element.replace. (I don't remember the regex to do the replace in one stroke, but this is the easy way)

paragraphElement.replace("<span>", "");
paragraphElement.replace("</span>", "");

Upvotes: 2

Shyju
Shyju

Reputation: 218732

$(function(){

   var newLbl=$("p").clone().find("span").remove().end().html();
    alert(newLbl);

});​

Example : http://jsfiddle.net/7gWdM/6/

Upvotes: 1

Matti Virkkunen
Matti Virkkunen

Reputation: 65126

It's just three text nodes instead of one. It doesn't make a visible difference does it?

If it's a problem, use the DOM normalize method to combine them:

$(...)[0].normalize();

Upvotes: 1

Related Questions