I've got a little text node:
var node
And I want to wrap a span around every occurrence of "lol".
node.nodeValue = node.nodeValue.replace(/lol/, "<span>lol</span>")
It it prints out "<span>lol<span>"
when I want "lol"
as a span element.
Show activity on this post. var http = require("http"); var getGitKey = function (context, callback) { http. get("http://integration.twosmiles.com/status", function(res) { var data = ""; res. on('data', function (chunk) { data += chunk; }); res.
The <ins> tag defines a text that has been inserted into a document. Browsers will usually underline inserted text. Tip: Also look at the <del> tag to markup deleted text.
createTextNode() Creates a new Text node. This method can be used to escape HTML characters.
The answer presented by Andreas Josas is quite good. However the code had several bugs when the search term appeared several times in the same text node. Here is the solution with those bugs fixed and additionally the insert is factored up into matchText for easier use and understanding. Now only the new tag is constructed in the callback and passed back to matchText by a return.
Updated matchText function with bug fixes:
var matchText = function(node, regex, callback, excludeElements) { excludeElements || (excludeElements = ['script', 'style', 'iframe', 'canvas']); var child = node.firstChild; while (child) { switch (child.nodeType) { case 1: if (excludeElements.indexOf(child.tagName.toLowerCase()) > -1) break; matchText(child, regex, callback, excludeElements); break; case 3: var bk = 0; child.data.replace(regex, function(all) { var args = [].slice.call(arguments), offset = args[args.length - 2], newTextNode = child.splitText(offset+bk), tag; bk -= child.data.length + all.length; newTextNode.data = newTextNode.data.substr(all.length); tag = callback.apply(window, [child].concat(args)); child.parentNode.insertBefore(tag, newTextNode); child = newTextNode; }); regex.lastIndex = 0; break; } child = child.nextSibling; } return node; };
Usage:
matchText(document.getElementsByTagName("article")[0], new RegExp("\\b" + searchTerm + "\\b", "g"), function(node, match, offset) { var span = document.createElement("span"); span.className = "search-term"; span.textContent = match; return span; });
If you desire to insert anchor (link) tags instead of span tags, change the create element to be "a" instead of "span", add a line to add the href attribute to the tag, and add 'a' to the excludeElements list so that links will not be created inside links.
The following article gives you the code to replace text with HTML elements:
http://blog.alexanderdickson.com/javascript-replacing-text
From the article:
var matchText = function(node, regex, callback, excludeElements) { excludeElements || (excludeElements = ['script', 'style', 'iframe', 'canvas']); var child = node.firstChild; do { switch (child.nodeType) { case 1: if (excludeElements.indexOf(child.tagName.toLowerCase()) > -1) { continue; } matchText(child, regex, callback, excludeElements); break; case 3: child.data.replace(regex, function(all) { var args = [].slice.call(arguments), offset = args[args.length - 2], newTextNode = child.splitText(offset); newTextNode.data = newTextNode.data.substr(all.length); callback.apply(window, [child].concat(args)); child = newTextNode; }); break; } } while (child = child.nextSibling); return node; }
Usage:
matchText(document.getElementsByTagName("article")[0], new RegExp("\\b" + searchTerm + "\\b", "g"), function(node, match, offset) { var span = document.createElement("span"); span.className = "search-term"; span.textContent = match; node.parentNode.insertBefore(span, node.nextSibling); });
And the explanation:
Essentially, the right way to do it is…
- Iterate over all text nodes.
- Find the substring in text nodes.
- Split it at the offset.
- Insert a span element in between the split.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With