Reputation: 21
I am trying to replace the font color of "bad" throughout an HTML page to red but there are two main issues, firstly it repeats the entire sentence before replacement and I do not want that and also the bad in "badly" was also replaced but I just want only the font in the word "bad" replaced. How do I go about this? Here is my code
window.onload = function() {
var text = document.getElementById("content");
var str = text.innerHTML,
reg = /red/ig;
var toStr = String(reg);
var color = (toStr.replace('\/g', '|')).substring(1);
var colors = color.replace("|");
if (colors.indexOf("red") > -1) {
str = str.replace(/bad/g, '<span style="color:red;">bad</span>');
}
document.getElementById("updated").innerHTML = str;
}
<div id="content">are they good or bad, tell me how badly it is if bad.</div>
<div id="updated"></div>
Upvotes: 1
Views: 81
Reputation: 20228
To replace text in HTML documents, it is a good idea to traverse the DOM tree and replace the content of text nodes where needed.
To match complete words only ("bad" but not "badly"), use regex with word boundary anchors \b
.
The following implementation performs depth-first DOM tree traversal and replaces text nodes containing the word "bad" with text nodes for both the text before and after that word as well as a <span style="color: red">bad</span>
in place of "bad":
var walk = (node, func) => {
var children = node.childNodes;
for (var i = children.length - 1; i >= 0; --i) {
walk(children[i], func);
}
func(node);
};
var highlight = (text, color) => {
var span = document.createElement("span");
span.style.color = color;
span.appendChild(document.createTextNode(text));
return span;
};
var root = document.getElementById("content");
walk(root, (node) => {
if (node.nodeType != Node.TEXT_NODE) return;
var texts = node.data.split(/\bbad\b/),
length = texts.length;
if (length > 1) {
var fragment = texts.reduce((fragment, text, i) => {
fragment.appendChild(document.createTextNode(text));
if (i < length - 1) fragment.appendChild(highlight("bad", "red"));
return fragment;
}, document.createDocumentFragment());
node.parentNode.replaceChild(fragment, node);
}
});
<div id="content">are they good or bad, tell me how badly it is <bad>bad bad bad</bad> if bad.</div>
See also: JavaScript: Add elements in textNode
Upvotes: 0
Reputation: 979
use \b (a word boundary token) as said by raphael75
str = str.replace(/\b(bad)\b/gi, '<span style="color:red;">$1</span>');
also, I:
var str = "bad incredibad badly Bad, testing bad, bad. bad";
str = str.replace(/\b(bad)\b/gi, '<span style="color:red;">$1</span>');
document.getElementsByTagName('p')[0].innerHTML = str;
<p></p>
regex101 is a go-to place for JavaScript RegEx
Upvotes: 1