tags:

views:

442

answers:

5

I have the following markup generated dynamically with a split and join function

<span>
    <em style="position: relative;">T</em>
    <em class="good" style="position: relative;">H</em>
    <em style="position: relative;">E</em>
    <em style="position: relative;">S</em>
</span>

I want to remove the em tag for the elements that do not have class "good" on. Get something like this:

<span>
    T <em class="good" style="position: relative;">H</em> ES
</span>

I figured that I can use the unwrap for this but it does not work:

$(document).ready(function(){
$("#njoin").live('click', function(){
$('em').each(function() {
    if ($(this).hasClass('good')) {
         $('.good').unwrap();
    }
});         
});
});

What should I do to make it work? Thank you

+2  A: 
$('em').each(function(){
if(!$(this).hasClass('good'))
   $(this).remove();
});

Should be as simple as that.

Mech Software
Wouldn't that remove the whole element (including the text?) I think he wants to keep what's inside the <em>
JayTee
@JayTee that is a good question. If he's doing this to change the class or style he's better off not trying to remove the <em> and changing the CSS to be non-bolded,etc. Doesnt make a lot of sense to try to remove the EM and keep the contents. It makes no difference to the in-memory DOM if the style is changed or if the <em> around it is removed. :) If that is the case he should change the CSS on it.
Mech Software
This function also removes the text from the <em> tag. I want to keep it.Thanx
Mircea
@Mircea - Why do you want to remove the tag? Is it for styling purposes?
Mech Software
@Mech - the nested ems are generated. There may be up to 200 and I do not want to stress the DOM with all theat. Only few ems that will be changed, with class good, should remain.
Mircea
@Mircea - You're already stressing the DOM by putting them in there in the first place. You'll further slow down your page having jquery iterate through 200 elements or more on the page to remove them. I suggest not putting 200 EM's in your document if you only need them on half a dozen. Manipulating a page like this just to make things "better" is kind of like putting the cart before the horse. You need to remove those EM's up the stream in the PHP or other code generating them.
Mech Software
A: 

you can try

$('#njoin').click(function() {
    $('em').each(function() {
        if($(this:not).hasClass('good')) {
            $('.good').remove();
        }
    });
});
Catfish
$('.good').remove(); will also remove the text in the <em> tag. I need to keep the text.
Mircea
A: 

jQuery 1.4 introduced the unwrap() function (as you mentioned) - do you have an issue with adding a tag?:

$('em:not(".good")')
  .each(function() { this.innerHTML = '<span>' + this.innerHTML + '</span>'; })
  .find('span').each(function() { $(this).unwrap(); });

Result:

<span><span>T</span> <em class="good" style="position: relative;">H</em> <span>E</span><span>S</span></span>
JayTee
There may be up tp 200 characters, only few of them will have the class "good" the rest will be just nested <em>s. THis is why I want to remove the rest. I think that there is no need to clog the DOM with useless tags
Mircea
you can't unwrap a text Node - because jQuery can't select a text node. Have you considered using your server-side processing to eliminate the additional tags?
JayTee
Not yet, but thanx, I'll look into that
Mircea
+1  A: 

This:

$('em:not(.good)').replaceWith(function(){
    return document.createTextNode($(this).text());
});

If you need to prevent spaces between any of the resulting elements, don't put spaces between them in your original HTML.

Adam Backstrom
It does remove the extra em but messes out the text. Some letters are repeated. I can't not put spaces in the orig html because the text must be readable. Thanx
Mircea
They're not repeated in my testing. Are you able to link to some live code that's causing problems, and let me know which browser you're using?
Adam Backstrom
I am on a FireFox 3.5.7. Unfortunately I am working local and can not update all the source right now. Thanx for the support.
Mircea
A: 

As others have suggested, it would really be ideal to remove the excess html from the page so it is never passed to the client, but this should work for your situation:

$("#njoin").live('click', function(){
    $('em').each(function(){ 
        if(!$(this).hasClass('good')) 
        {
            this.outerHTML = $(this).html();
        }
    });
});

Edit: Working example

rosscj2533
this.outerHTML = $(this).html();This does nothing right now. Maybe I can append or replace this...
Mircea
Hmmm, maybe somewhere out html is different. I'll post a working example and see if that helps you figure it out.
rosscj2533