Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change text inside span with jQuery, leaving other span contained nodes intact?

I have the following HTML snippet:

<span class="target">Change me <a class="changeme" href="#">now</a></span>

I'd like to change the text node (i.e. "Change me ") inside the span from jQuery, while leaving the nested <a> tag with all attributes etc. intact. My initial huch was to use .text(...) on the span node, but as it turns out this will replace the whole inner part with the passed textual content.

I solved this with first cloning the <a> tag, then setting the new text content of <span> (which will remove the original <a> tag), and finally appending the cloned <a> tag to my <span>. This works, but feels such an overkill for a simple task like this. Btw. I can't guarantee that there will be an initial text node inside the span - it might be empty, just like:

<span class="target"><a class="changeme" href="#">now</a></span>

I did a jsfiddle too. So, what would be the neat way to do this?

like image 696
András Szepesházi Avatar asked Jan 18 '23 08:01

András Szepesházi


2 Answers

Try something like:

$('a.changeme').on('click', function() {
  $(this).closest('.target').contents().not(this).eq(0).replaceWith('Do it again ');
});

demo: http://jsfiddle.net/eEMGz/

ref: http://api.jquery.com/contents/

Update:

I guess I read your question wrong, and you're trying to replace the text if it's already there and inject it otherwise. For this, try:

$('a.changeme').on('click', function() {
  var
    $tmp = $(this).closest('.target').contents().not(this).eq(0),
    dia = document.createTextNode('Do it again ');

  $tmp.length > 0 ? $tmp.replaceWith(dia) : $(dia).insertBefore(this);
});

​Demo: http://jsfiddle.net/eEMGz/3/

like image 102
Yoshi Avatar answered Jan 31 '23 09:01

Yoshi


You can use .contents():

//set the new text to replace the old text
var newText = 'New Text';

//bind `click` event handler to the `.changeme` elements
$('.changeme').on('click', function () {

    //iterate over the nodes in this `<span>` element
    $.each($(this).parent().contents(), function () {

        //if the type of this node is undefined then it's a text node and we want to replace it
        if (typeof this.tagName == 'undefined') {

            //to replace the node we can use `.replaceWith()`
            $(this).replaceWith(newText);
        }
    });
});​

Here is a demo: http://jsfiddle.net/jasper/PURHA/1/

Some docs for ya:

  • .contents(): http://api.jquery.com/contents
  • .replaceWith(): http://api.jquery.com/replacewith
  • typeof: https://developer.mozilla.org/en/JavaScript/Reference/Operators/typeof

Update

var newText = 'New Text';
$('a').on('click', function () {
    $.each($(this).parent().contents(), function () {
        if (typeof this.tagName == 'undefined') {

            //instead of replacing this node with the replacement string, just replace it with a blank string
            $(this).replaceWith('');
        }
    });

    //then add the replacement string to the `<span>` element regardless of it's initial state
    $(this).parent().prepend(newText);
});​

Demo: http://jsfiddle.net/jasper/PURHA/2/

like image 26
Jasper Avatar answered Jan 31 '23 09:01

Jasper