2

Possible Duplicate:
Remove text with jQuery

<div class="pun-crumbs"><p class="crumbs">
<a href="/">Forum</a>
<strong>
 »
<a class="nav" href="/c4-our-mods">Test</a>
 » 
<a class="nav" href="/f7-forum">
<span>Test 1</span>
</a>
</strong>
</p>
</div>

How do I remove the second '»' via jquery ? Thanks for answering my question :) . Note: I can't edit the html.

Community
  • 1
  • 1

3 Answers3

5

jQuery doesn't have much support for text nodes so if the text you're looking for isn't wrapped in it's own element, then you can do it something like this:

var cntr = 0;
$(".pun-crumbs strong").contents().each(function() {
    // nodeType 3 is text nodes
    // nodeValue is the contents of a text node
    if (this.nodeType == 3 && this.nodeValue.indexOf("»") != -1) {
        ++cntr;
        if (cntr == 2) {
           this.parentNode.removeChild(this);
        }
    }
});

You can see it work here: http://jsfiddle.net/jfriend00/5AdNM/

This is generally advantageous over code that modifies innerHTML because this code won't mess with any event handlers that may already be applied whereas assigning a new, changed value to innerHTML will wipe out any event handlers (because it recreates new DOM objects).

This version of the code removes the whole text node that contains the chevron because that looked to be the most convenient things for your particular HTML. If you wanted to leave other text in that text node, you could use .replace() to remove just the chevron from the text mode and leave the other text.

This other version of the code would remove just the chevron, leaving other stuff in that text node:

var cntr = 0;
$(".pun-crumbs strong").contents().each(function() {
    // nodeType 3 is text nodes
    // nodeValue is the contents of a text node
    if (this.nodeType == 3 && this.nodeValue.indexOf("»") != -1) {
        ++cntr;
        if (cntr == 2) {
           this.nodeValue = this.nodeValue.replace("»", "");
        }
    }
});​

You can see this one work here: http://jsfiddle.net/jfriend00/XsnEW/

If you control the HTML and can put the chevrons in their own span with a unique class name on them, then it's a lot easier to do with plain jQuery.

Here's a bit simpler version that removes the chevron text node:

$(".pun-crumbs strong").contents().filter(function() {
    return (this.nodeType == 3 && this.nodeValue.indexOf("»") != -1);
}).eq(1).remove();

or modifies it:

var textNode = $(".pun-crumbs strong").contents().filter(function() {
    return (this.nodeType == 3 && this.nodeValue.indexOf("»") != -1);
}).get(1);
textNode.nodeValue = textNode.nodeValue.replace("»", "");
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • 1
    I prefer Lix's code but your explaination is detailed and easy to understand. Thanks :) . – Mark Nguyen Mar 18 '12 at 20:34
  • 1
    There are side effects to modifying innerHTML of a bunch of objects (like losing event handlers). It is generally safer not to do search replace on innerHTML of multiple objects. I added a couple even shorter versions. – jfriend00 Mar 18 '12 at 20:42
  • Hello, i have another problem. can you do it without the "strong" tag. Sometimes, it has "strong" tag but sometimes it doesnt. Thanks. – Mark Nguyen Mar 18 '12 at 20:53
  • @MarkNguyen - You can just change `$(".pun-crumbs strong")` to `$(".pun-crumbs")` and it will work without the ``. – jfriend00 Mar 18 '12 at 21:21
2

This should solve your issue.
It is a slight variation of the original edit to this post that was changed during the grace period.

var container = $('div.pun-crumbs');
container.html(container.html().replace(/»/g,'')).find('strong').prepend('»');

The main difference here is that I'm using regular expression syntax to replace all instances of the » character and only then prepending one of them back.

Community
  • 1
  • 1
Lix
  • 47,311
  • 12
  • 103
  • 131
  • Didn't copy my original answer at all. – Austin Brunkhorst Mar 18 '12 at 20:30
  • I'll be honest - I commented on your answer at first - it looked correct. But after testing it I found that It didn't work - so I improved/fixed it and posted my own answer. If this offends you by all means let me know and I'll remove this post. No hard feelings. I mean no disrespect. – Lix Mar 18 '12 at 20:34
  • 1
    I'm glad I didn't offend you Mark :) But I was actually replying to @AustinBrunkhorst – Lix Mar 18 '12 at 20:58
  • Didn't see that, let me fix my eyes :) . – Mark Nguyen Mar 18 '12 at 20:59
  • 1
    No hard feelings taken. Sorry, it's just that I've been in too many situations where people don't have the slightest consideration of other's work. But this isn't the case. Thanks Lix! – Austin Brunkhorst Mar 18 '12 at 21:09
  • 1
    NP @AustinBrunkhorst - If you are seeing that a lot this might interest you - http://meta.stackexchange.com/questions/112084/handling-answers-that-build-heavily-on-or-are-copied-outright-from-existing-an – Lix Mar 18 '12 at 21:10
0

Try

var container = $('p.crumbs strong');
container.html(container.html().replace(/»/g,''));

var crumbs = container.find('a.nav');
$.each(crumbs, function(i, crumb){
    if(i != crumbs.length - 1)
        $(crumb).before('»');
});​

Final Edit, a JSFiddle can be found here - http://jsfiddle.net/M5hE3/

Austin Brunkhorst
  • 20,704
  • 6
  • 47
  • 61