Your example is a bit ambiguous, because the Bar
instances are the only things that are directly contained by body
. If I assume you may have other things than Bar
in that section, no, you can't apply CSS just to the Bar
parts and not to the other parts.
In JavaScript, you could wrap the Bar
text in an element (say, a span
) and then style that element. The simple naive way is to use replace
:
// Simple, but naive, and probably not what you want
document.body.innerHTML = document.body.innerHTML.replace(/\bBar\b/g, '<span class="wrapper">Bar</span>');
Here's an example, but keep reading:
document.body.innerHTML = document.body.innerHTML.replace(/\bBar\b/g, '<span class="wrapper">Bar</span>');
.wrapper {
font-weight: bold;
color: green;
}
<p>Foo</p>
Bar
Glarb
Bar
Glarb
Bar
<p>Foo</p>
<div>
<p>Foo</p>
Bar
Glarb
Bar
Glarb
Bar
<p>Foo</p>
</div>
The problems with doing that are:
Bar
will be matched everywhere, even in attributes and such
- It will blow away the page entirely, and replace all of the elements on the page with new elements. That will disconnect event handlers, for instance.
So instead, you can do something more refined, find the text within text nodes and only wrap it when you find it, which A) Doesn't find it in the wrong place, and B) Doesn't affect event handlers on existing elements.
My answer here demonstrates how to wrap a portion of the text in a text node in another element. Here it is applied to your specific situation:
walk(document.body, "Bar");
function walk(node, targetString) {
var child;
switch (node.nodeType) {
case 1: // Element
for (child = node.firstChild; child; child = child.nextSibling) {
walk(child, targetString);
}
break;
case 3: // Text node
handleText(node, targetString);
break;
}
}
function handleText(node, targetString) {
var start, targetNode, followingNode, wrapper;
// Does the text contain our target string?
// (This would be a regex test in your http://... case)
start = node.nodeValue.indexOf(targetString);
if (start >= 0) {
// Split at the beginning of the match
targetNode = node.splitText(start);
// Split at the end of the match
followingNode = targetNode.splitText(targetString.length);
// Wrap the target in an element; in this case, we'll
// use a `span` with a class, but you'd use an `a`.
// First we create the wrapper and insert it in front
// of the target text.
wrapper = document.createElement('span');
wrapper.className = "wrapper";
targetNode.parentNode.insertBefore(wrapper, targetNode);
// Now we move the target text inside it
wrapper.appendChild(targetNode);
// Clean up any empty nodes (in case the target text
// was at the beginning or end of a text ndoe)
if (node.nodeValue.length == 0) {
node.parentNode.removeChild(node);
}
if (followingNode.nodeValue.length == 0) {
followingNode.parentNode.removeChild(followingNode);
}
}
}
.wrapper {
font-weight: bold;
color: green;
}
<p>Foo</p>
Bar
Glarb
Bar
Glarb
Bar
<p>Foo</p>
<div>
<p>Foo</p>
Bar
Glarb
Bar
Glarb
Bar
<p>Foo</p>
</div>