Matt Welander
Matt Welander

Reputation: 8548

jquery remove <span> tags while preserving their contents (and replace <divs> and <p>:s with <br>)

is there a good way to remove all SPAN tags (while preserving the text inside of them) and replacing all DIVs and P's with BR? Using jQuery?

<div>
 <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin rutrum tincidunt urna ac dignissim. Phasellus nisi ante, pharetra at
 <span>&nbsp;lorem a, condimentum ullamcorper</span>
 <span>&nbsp;leo. Duis pharetra nulla sit amet dui feugiat luctus.</span>
</p>
<p>
 <span>Ut eget nulla pulvinar ligula tincidunt placerat ut in eros. Cras posuere eget lacus eu lacinia. Cras lacinia porta porta. In hac habitasse platea dictumst. Maecenas nibh ligula, vulputate ut suscipit congue, euismod sed nunc. Cras quis rhoncus justo, sit amet vulputate enim.</span>
</p>
</div>

I am fighting a contentEditable issue and trapping certain keydowns is not an option, this needs to be completely cross browser valid and issu with both return (new lines), backspace and delete buttons.

Upvotes: 3

Views: 9868

Answers (5)

Le Tung Anh
Le Tung Anh

Reputation: 909

Add style display:inline-block; to contenteditable, it will not generate div, p, span automatic in chrome

Upvotes: -2

Matt Welander
Matt Welander

Reputation: 8548

Here's how I managed to get it working, led by Raphaels answer

        if( $(textObject).children().length > 0 ) {
            $(textObject).children().each(function() {

                if ( $(this).is("span") ) {
                    $(this).contents().unwrap();
                }
                else if ( $(this).is("div") || $(this).is("p") ) {
                    $(this).prepend('<br />').contents().unwrap();
                }

                restoreTextFormat(this);
            });
        }

I have a feeling this nesting business is maybe taking up too much resources though, is there a neat way to optimize this little block of code?

Upvotes: 5

Niet the Dark Absol
Niet the Dark Absol

Reputation: 324750

Using basic VanillaJS:

// this function does the hard work for us
function unwrap(root,tagname,extra) {
    var elms = root.getElementsByTagName(tagname), l = elms.length, i;
    for( i=l-1; i>=0; i--) {
        // work backwards to avoid possible complications with nested spans
        while(elms[i].firstChild)
            elms[i].parentNode.insertBefore(elms[i].firstChild,elms[i]);
        if( extra) extra(elms[i]);
        elms[i].parentNode.removeChild(elms[i]);
    }
}

// assumes "container" is a pointer to your container, such as from
// using document.getElementById('container') or similar
unwrap(container,"span"); // remove all spans, preserving their content
unwrap(container,"div",function(elm) {
    elm.parentNode.insertBefore(document.createElement('br'),elm);
});
unwrap(container,"p",function(elm) {
    elm.parentNode.insertBefore(document.createElement('br'),elm);
});

Hope this helps!

Upvotes: 2

Asteroid
Asteroid

Reputation: 57

Please try to add a div named parent and edit the html.

$(this).find('#parent').html($(this).find('#parent').html().replace('<div>', '').replace('</div>', '<br/>').replace('<p>', '').replace('</p>', '<br/>').replace('<span>', '').replace('</span>', ''));

This might solve your purpose. Atleast give you an idea.

Upvotes: -2

Rapha&#235;l Althaus
Rapha&#235;l Althaus

Reputation: 60503

you may do something like that

//remove all span tags, keeping the content
$('span').contents().unwrap();
//add a br at the start of each p or div, then remove p or div 
//use append instead of prepend to add the  line break at the end, not at the start.
$('p, div').prepend('<br />')
           .contents().unwrap();

see jsFiddle

Upvotes: 2

Related Questions