Reputation: 7765
I need to match text within a string, using JavaScript or jQuery, at any DOM level, which isn't part of an HTML tag. So, for example, I need to match the word foo
in the following passage exactly 5 times:
Foo <p class="foobar" id='foo'>foobar foo<a href="/foo">foo</a> foo.</p>
I need to keep the full text intact, with tags, for later use. This is to wrap each result in a <span />
tag using find/replace, an effort which currently fails when it incorrectly matches parts of tags and links.
It seems obvious to use jQuery's .html()
method, but this means I have to dodge those pesky tags. The necessary regex is getting too complicated for me to handle. (I also know regex on HTML carries some risk; I'm open to another approach.)
For example, I tried using jQuery's .text()
method, which lets me manipulate the text as I want using find/replace, but it's seemingly impossible then to update the page source, because you're dealing with the DOM's text node: it won't let me insert those <span>
tags into the source.
Otherwise, I'm stumped. Thanks!
Upvotes: 1
Views: 182
Reputation: 26434
To target selectors that contain a particular string, use jQuery's contains
selector. You can then iterate over all such elements with the each
function.
$('*:contains("foo")').each(function() {
$(this).html("<span class='bold'>" + $(this).text() + "</span>");
});
It should be noted that the contains
selector is case sensitive! We need to modify the jQuery method to allow Foo
to be found. Add this code to your jQuery file.
jQuery.expr[':'].contains = function(a, i, m) {
return jQuery(a).text().toUpperCase()
.indexOf(m[3].toUpperCase()) >= 0;
};
Another solution is to use jQuery's filter
function like so
var selection = $("*").filter(function() {
return /FOO/i.test($(this).text());
});
This is probably a better practice because you don't have to modify the original jQuery code. The test
method takes a regular expression and returns a Boolean
on whether or not a string contains said expression. The /i
flag makes the regex case insensitive. It will match the following
Upvotes: 1
Reputation: 143
To access just the text use the .text() method, so : (had to escape single quotes)
$('<div>Foo <p class="foobar" id=\'foo\'>foobar foo<a href="/foo">foo</a> foo.</p></div>').text()
returns: "Foo foobar foofoo foo."
Do what you will from there.
Upvotes: 1