I\'m running into a little problem when I try to put a variable inside a string that\'s already inside a string. Basically, I\'m trying to change the color of a specific wor
An easy solution would be to simply replace the innerHTML
property of your element by a new html string that would have wrapped the words in a span
. However, it's not a very flexible solution, since by replacing the innerHTML
property, all the elements would be renewed and that might give unexpected results, unless you target elements that only holds text nodes.
Lets suppose the body
contains this text:
this is some text and I want to replace the word cool
You could have:
var $body = $(document.body);
$body.html($body.html().replace(/\b(cool)\b/g, '<span style="color: red;">$1</span>'));
Here the /\b(cool)\b/g
regex will match every cool words and create a capturing group on them, allowing us to reference it in the replacement expression as $1
.
However, a most advanced solution could probably be implemented like:
span
that has a data-styled-text
attribute. (you could check the textNode.parentNode
property)<span data-styled-text>
tag. Have a look at https://developer.mozilla.org/fr/docs/DOM/Text.splitText<span data-styled-text>
elements and do whatever manipulation you want with them.I have toyed around with that concept and I have create a fiddle for you that shows how you could manipulate text in any ways you want using a regex
to target specific text. I have created 2 main functions wrapText
and styleText
that will allow you to do whatever you want with text on the page. It could be further optimzed, but you will get the idea.
Have a look at http://jsfiddle.net/scarsick/tX4Ge/1/
The following function allows you to wrap any text in a text node.
function wrapText(textNode, textRx, wrapFn) {
var global = textRx.global,
wrapEl,
result,
rightTextNode,
matchedText,
index;
while (result = textRx.exec(textNode.nodeValue)) {
rightTextNode = textNode.splitText(index = result.index);
rightTextNode.nodeValue = rightTextNode.nodeValue.substring((matchedText = result[0]).length);
wrapEl = wrapFn(matchedText, index);
wrapEl.appendChild(document.createTextNode(matchedText));
rightTextNode.parentNode.insertBefore(wrapEl, rightTextNode);
if (!global) {
break;
}
textNode = rightTextNode;
textRx.lastIndex = 0;
}
}
The following function allow you to style any text contained within an element.
function styleText(el, textRx, styleFn) {
var wrapEl = document.createElement('span'),
slice = [].slice;
wrapEl.setAttribute('data-styled-text', 'true');
styleText = function(el, textRx, styleFn) {
var childNodes = slice.call(el.childNodes, 0),
i = 0,
len = childNodes.length,
node;
for (; i < len; i++) {
node = childNodes[i];
switch (node.nodeType) {
case 3:
if (!node.parentNode.getAttribute('data-styled-text')) {
wrapText(node, textRx, function (text, index) {
var el = wrapEl.cloneNode();
styleFn(el, text, index);
return el;
});
continue;
}
styleFn(node.parentNode);
break;
case 1:
styleText(node, textRx, styleFn);
break;
}
}
};
styleText(el, textRx, styleFn);
}
If all of that code exists only to change the colour of the text in the element, you can simplify it greatly like so:
var color = "#ff8877";
$('#textWithTheWord').css('color', color);
http://api.jquery.com/css/
There's no need to play about with the DOM or string concatenation to change attributes or styling of an element. jQuery will likely have a function that does what you want already.