views:

153

answers:

4

I'm trying to figure out the jQuery statement to rename "apple" with "orange:"

<a id="alvin" href="http://www.camille.com"&gt;&lt;ins class="xxx">Anna</ins>apple</a>

Can this be done easily?

+1  A: 

I removed the # from the ID, since it is not a valid ID character.

Given that, try this:

Live Example: http://jsfiddle.net/u49wy/

var $contents = $('#alvin').contents();

$contents[$contents.length - 1].nodeValue = 'orange';

.contents() returns all the child nodes of the element, including text nodes.

The code then grabs the last element node (which is a text node) and updates its nodeValue, which is how you update the value of a text node.

patrick dw
+1, you beat me to it, although I've still posted my solution because it differs slightly :-)
Andy E
@Andy - Thanks for the +. Yeah, mine operates with the assumption of specific positioning. It'll be a toss up depending on the specific needs of OP.
patrick dw
Thanks! I knew it could be done. I wish I could award multiple solutions like E*-E*.com (to Andy, too).
Pete Alvin
@Pete: Yeah, it would be nice, I've wanted to do that a few times. But don't worry, I don't mind - patrick did get in there first :-)
Andy E
@Andy - Just imagine how many redundant answers people would post if multiples could be Accepted. Redundancy in the first couple minutes is understandable, but I think *that* would be enough to drive me out of here. :o)
patrick dw
@patrick: Yeah, the only time I can see it being useful (and the only time I've ever thought about it) is when you reach a solution that is assisted by someone else, but their answer isn't the solution.
Andy E
@Andy - Interesting. Would be cool if when John Doe is assisted by another user's answer, John Doe could *link* to the other answer (as a courtesy) so that if John Doe's answer is accepted, the other user would also get some credit. Anyway, getting off topic. A discussion better suited for META.
patrick dw
+1  A: 

patrick beat me to it, but my solution is a little more dynamic in that it would select the text anywhere, even if there were tags on either side:

$('#alvin').contents().filter(function () {
    return this.nodeType == 3;
})[0].nodeValue = "orange";

It does this by filtering the contents so that only text nodes remain, and changes the first nodeValue to "orange".

http://jsfiddle.net/ssRyB/

Andy E
Thanks! I wish I could award multiple solutions like E*-E*.com.
Pete Alvin
+1  A: 

id="#alvin" is not valid syntax, '#' is used as part of a selector for jQuery or in CSS.

For this very limited example, replace "apple" with "orange" I would actually simply read the innerHTML and rewrite it. I'm not even using jQuery for this.

window.onload = function() {
    var alvin = document.getElementById('alvin')
    alvin.innerHTML = alvin.innerHTML.replace('apple', 'orange');
}

I used no jQuery because jQuery does not have a clean way to select stray text nodes. So what if we wrapped any child text nodes in spans? We could do this:

$('#alvin').contents().filter(function() {
  return this.nodeType == 3;
}).wrap('<span></span>').end();

In that way, we are left with the structure:

<a id="alvin" href="http://www.camille.com"&gt;&lt;ins class="xxx">Anna</ins><span>apple</span></a>

Then we can use the + adjacent selector to get at it, like this -- ins+span means a <span> after an <ins>:

var elem = $('#alvin ins+span');
elem.text(elem.text().replace('apple', 'orange'));
artlung
Not much jQuery in there... ;)
Gert G
Yeah, I wasn't very happy with my answer either. I've added a 2nd approach.
artlung
I corrected the syntax; thanks!
Pete Alvin
A: 

Another way (not very pretty though):

$("#alvin").html($("#alvin").html().replace(/apple$/,'orange'));

Edit: Added the $ at the end of apple. Thanks Patrick.

Gert G
@Gert - It actually won't work with the closing `a` tag, since it is not part of the content of `#alvin`. The `.html()` method will only return the inner HTML content. Not any part of the tag set matched by the selector. You could use an end of input indicator `$`, though. :)
patrick dw