Reputation: 430
I try to find and replace text (using jQuery). Actually I'm trying to add a span element around the text. I should also be able to remove the span again without losing the text inside.
For example, let's say I have the following situation to start with:
<span>This is a span element</span>
And I want to be able to do this dynamically using jQuery/JavaScript:
<span>This is a <span class="marked">span</span> element</span>
I should also be able to remove the span.marked and get back to the first result.
The problem however is that I want to do this on all text inside a container with multiple children and subchildren and so on.
The code I got so far will do the following and that is not what I want:
<<span class="marked">span</span>>This is a <span class="marked">span</<span class="marked">span</span> element</span>
I want to do this for ALL text on the page, not just the first it finds.
EDIT: my code so far for doing this:
var re = new RegExp(word, 'g');
$('.container').html($('.container').html().replace(re, '<span class="marked">' + word + '</span>'));
word is a string with the text to wrap spans around.
Upvotes: 8
Views: 40894
Reputation: 1460
$('.container p').each(function() {
var text = $(this).text();
$(this).html(text.replace('word', '<strong><span class="accordion">word </span></strong>'));
});
Upvotes: 6
Reputation: 324507
Don't use a regular expression. Use DOM traversal, which will be much more reliable, faster and less destructive (event handlers are not destroyed, for example).
See https://stackoverflow.com/a/10618517/96100 for a simple example.
Alternatively, you could use the following:
http://james.padolsey.com/javascript/replacing-text-in-the-dom-solved/
This doesn't cover removing the spans afterwards but that is a reasonably simple matter. Something like the following (untested):
function replaceWithOwnChildren(el){
var parent = el.parentNode;
while (el.hasChildNodes()) {
parent.insertBefore(el.firstChild, el);
}
parent.removeChild(el);
}
// Create a non-live standard array of spans
var spans = [].slice.call(document.getElementsByTagName("span"), 0);
for (var i = 0, len = spans.length; i < len; ++i) {
if (spans[i].className == "marked") {
replaceWithOwnChildren(spans[i]);
}
}
// Glue together any adjacent text nodes
document.normalize();
Upvotes: 2
Reputation: 161
var mark = function(word){ return function(){ this.innerHTML = this.innerHTML.replace(word,'' + word + ''); } }; $('span').each(mark('span'));
Upvotes: 1
Reputation: 1621
To wrap a search string in html you can use something like this:
$('span:contains("word")').html().replace('word', '<span class="marked">word</span>');
and to remove it, you can use something like this:
$('span:contains("word")').html().replace('<span class="marked">word</span>', 'word');
Yes this is a pretty crude way of doing it but it should work.
EDIT: as pointed out by @user3558931, the word needs to be a variable.
To wrap a search string in html you can use something like this:
$('span:contains("' + str + '")').html().replace(str, '<span class="marked">' + str + '</span>');
and to remove it, you can use something like this:
$('span:contains("' + str + '")').html().replace('<span class="marked">' + str + '</span>', str);
EDIT: A glitch in the above code, see the fixed code in this fiddle: http://jsfiddle.net/thePav/7TNk6/21/
Upvotes: 11
Reputation: 24638
I believe the regular expression needs to be adjusted so it does not pick <span
or any other HTML tag for that matter. I would like to suggest the RegExp:
var re = new RegExp('[^<\\/](' + word + ')', 'g');
And the replacement:
$('.container').each(function() {
$(this).html( $(this).html().replace( re, ' <span class="marked">$1</span>' ) );
});
And can be reversed by using the code (Click button in demo below):
$('button.undo').on( 'click', function() {
$('.container').find( 'span.marked' ).each(function() {
$(this).replaceWith( word );
});
});
Upvotes: 1
Reputation: 7531
var span = document.getElementsByTagName("span")[0];
span.innerHTML = span.innerHTML.replace(/span/g, "<span class=\"marked\">span</span>");
Upvotes: 0
Reputation: 685
Try using following:
$('.container').forEach(function(){
$(this).html()....
})
If that is your problem that is. Otherwise, please clarify, what exactly isn't working as it is supposed to?
Upvotes: 0