JQuery change inner text but preserve html

Jquery

Jquery Problem Overview


I would like to change the text of a HTML element but preserve the rest of the inner html with jQuery.

For instance:

<a href="link.html">Some text <img src="image.jpg" /></a> 

replace "Some text" with "Other text", and the result should look like:

<a href="link.html">Other text <img src="image.jpg" /></a> 

EDIT: My current solution is following:

var aElem = $('a');
var children = aElem.children();
				
aElem.text("NEW TEXT");
aElem.append(children);	

But there must be some more elegant way of doing this.

Jquery Solutions


Solution 1 - Jquery

This seems to work just fine.

Live Demo

<html>
    <head>
    </head>
    <body>
        <a href="link.html">Some text <img src="img.jpg" /></a>
    </body>
    
    </html>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script>
    <script type="text/javascript">
        $(function(){
            var $link = $('a');
            var $img = $link.find('img'); 
            $link.html('New Text');
            $link.append($img);
        });
    </script>

Solution 2 - Jquery

Since you can't modify the link an option would be to simply use replace

$("a").html($("a").html().replace("Some text", "Other text"));

Example on jsfiddle.

Solution 3 - Jquery

Wrap the text you want to change in a span

<a href="link.html"><span>Some text</span> <img src="image.jpg" /></a> 

$('a span').html( 'new text' );

Solution 4 - Jquery

My solution, though a little late.

$('a').each(function() {
    var contents = $(this).contents();
    if (contents.length > 0) {
        if (contents.get(0).nodeType == Node.TEXT_NODE) {
            $(this).html('NEW TEXT').append(contents.slice(1));
        }
    }
});

Some notes:

  1. contents() includes text nodes, unlike children().
  2. It is necessary to create a copy of the contents via var contents = ... or else the remaining elements are lost forever once replaced by $(this).html('NEW TEXT').
  3. The length check is optional but recommended.
  4. The nodeType check is optional but recommended.

Solution 5 - Jquery

An alternative way would be to use the contents() method as follows:

Given

<a href="link.html">Some text <img src="image.jpg" /></a>

you can replace 'Some text' with jQuery

var text = $('a').contents().first()[0].textContent;
$('a').contents().first()[0].textContent = text.replace("Some text", "Other text");

jsFiddle example here.

The idea of contents() was inspired by this question, answered by user charlietfl.

Solution 6 - Jquery

You can change it by .contents()

$('.yourElement').contents()[0].data = 'New Data';

where in your case the "[0].data" is your text data

Solution 7 - Jquery

just use some plain js functionality:

$('a')[0].firstChild.nodeValue = "New Text";

Solution 8 - Jquery

try this code

$('a').live('click', function(){
    var $img = $(this).find('img'); 
    $(this).text('changed');
    $(this).append($img);
});

Solution 9 - Jquery

An efficient and robust way that doesn't require you to know what the inner elements are or what the text is:

var $a = $('a');
var inner = '';
$a.children.html().each(function() {
    inner = inner + this.outerHTML;
});
$a.html('New text' + inner);

Solution 10 - Jquery

You'll need to add in a <span> element and change the text of that element, e.g.:

<a href="link.html"><span id="foo">Some text</span><img src="image.jpg" /></a>

Then, you can call from jQuery:

$("#foo").html("Other text");

And your result will effectively be:

<a href="link.html"><span id="foo">Other text</span><img src="image.jpg" /></a>

Solution 11 - Jquery

This is an improvement I've made to the jquery.uniform library. Specifically the $.uniform.update() function. I took the idea from acheong87 and changed it a bit.

The idea is to change the text in a span but preserve the inner HTML and event bindings. No need to store and append HTML this way.

if ($e.is("input[type=button]")) {
    spanTag = $e.closest("span");
    var contents = spanTag.contents();
    
    if (contents.length) {
        var text = contents.get(0);
        
        // Modern browsers support Node.TEXT_NODE, IE7 only supports 3
        if (text.nodeType == 3)
            text.nodeValue = $e.val();
    }
}

Solution 12 - Jquery

I added a jQuery function for that need.

you may need to convert the html-entities to text representation, so i added decodeEntities function.

function decodeEntities(encodedString) {
 if (typeof encodedString != "string") return encodedString;
 if (!encodedString) return "";
 var textArea = document.createElement('textarea');
 textArea.innerHTML = encodedString;
 return textArea.value;
}
jQuery.fn.textOnly = function(n) {
  if (this.length > 0)
   $(this).html(decodeEntities($(this).html()).replace($(this).text(), n));
  return $(this);
 }

Usage example $('selector').textOnly('some text')

Solution 13 - Jquery

My generic version:

let button = $('#yourElement');
button.html(button.html().replace(button[0].innerText, "New Text"));
    

Solution 14 - Jquery

Shorthand for more elements and leading text to change:

elemshtml = '';
$("a *").each(function(){elemshtml +=$(this)[0].outerHTML});
$("a").html('Some text' + elemshtml);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDrejcView Question on Stackoverflow
Solution 1 - JqueryBrandon BooneView Answer on Stackoverflow
Solution 2 - JqueryMark ColemanView Answer on Stackoverflow
Solution 3 - JquerymeouwView Answer on Stackoverflow
Solution 4 - JqueryslackwingView Answer on Stackoverflow
Solution 5 - Jqueryjim_kastrinView Answer on Stackoverflow
Solution 6 - JqueryDarryl CeguerraView Answer on Stackoverflow
Solution 7 - JqueryDrea58View Answer on Stackoverflow
Solution 8 - JquerydiEchoView Answer on Stackoverflow
Solution 9 - JqueryanthonygoreView Answer on Stackoverflow
Solution 10 - JqueryBrian DriscollView Answer on Stackoverflow
Solution 11 - JqueryTim VermaelenView Answer on Stackoverflow
Solution 12 - JqueryYechezkel DerenView Answer on Stackoverflow
Solution 13 - JqueryoceanBTView Answer on Stackoverflow
Solution 14 - Jqueryuser3270784View Answer on Stackoverflow