RyBolt
RyBolt

Reputation: 1794

Replace only text contents of html element with jQuery, preserving font awesome i tags

Here is the test case:
<span id='loading' class="pad"> <i class="fa fa-spinner fa-pulse fa-lg fa-fw"></i> Loading map... </span>

I am trying to dynamically ( via jQuery ) , change only the "Loading map..." portion of this markup. I realize I can rebuild the whole inner contents every time , incorporating and replacing <i .... {new message here} ... </i> but I am curious to know if there is a supported api method for this.

I thought $('#loading').text('new message') would work but it removes the <i> tag.

Upvotes: 0

Views: 1222

Answers (4)

TheThirdMan
TheThirdMan

Reputation: 1522

If what you're trying to do is replace all text that isn't wrapped within any child element, the most general approach I can see is setting the content of the element to it's child elements (omitting the text-only content), then appending the desired text, like this:

$('#loading').html($('#loading').children()).append('new message');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span id='loading' class="pad">
  <div>static element of any kind</div>
  text to replace
</span>


However, the most straightforward way would be to define an element from the start, then set a new content for that.

$('#message').text('new message');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span id='loading' class="pad">
  <div>static element of any kind</div>
  <div id="message">text to replace</div>
</span>

Upvotes: 0

Mojtaba
Mojtaba

Reputation: 5002

function changeText(newText){
curI = $('#loading > i')[0].outerHTML;
$('#loading').html(curI + newText);
}

changeText('Hey. I am the new text');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<span id='loading' class="pad"> <i class="fa fa-spinner fa-pulse fa-lg fa-fw"></i> Loading map... </span>

By the way, if you could wrap the changeable text inside another tag, then, you could directly change it regardless the parent.

Upvotes: 1

palaѕн
palaѕн

Reputation: 73936

You can solve this using the .filter() method, like:

$('#loading').contents().filter(function() {
    return this.nodeType === 3
}).each(function(){
    this.textContent = this.textContent.replace('Loading map...','new message');
});

Simple Demo:

$('#loading').contents().filter(function() {
    return this.nodeType === 3
}).each(function(){
    this.textContent = this.textContent.replace('Loading map...','new message here...');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css">
<span id='loading' class="pad"> <i class="fa fa-spinner fa-pulse fa-lg fa-fw"></i> Loading map... </span>

If you check the browser console you will find <i class="fa fa-spinner fa-pulse fa-lg fa-fw"></i> element is still there, it just not shown here as font-awesome is not included here. (Edit: Added the fa css also.)

Upvotes: 0

Milind Anantwar
Milind Anantwar

Reputation: 82251

You can use get the object of text node and set the content using textContent:

$('#loading').contents().last()[0].textContent='new message';

$('#loading').contents().last()[0].textContent='new message';
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span id='loading' class="pad"> <i class="fa fa-spinner fa-pulse fa-lg fa-fw"></i> Loading map... </span>

Upvotes: 3

Related Questions