I am writing a JavaScript script that will walk the DOM
and wrap a specific keyword in a <span>
tag. I want my script
to wrap any occurrences of the word pan
in a <span>
so I can style it using <span style='color: red'
. I don't actually want to use the word, pan
, I am just using it as an example.
I have already reviewed many similar posts here, but none of them solve my problem. Most are either nuclear, over-complicated and confusing, or over-simplified and do not work as I've intended.
Here is what I have written so far:
<html> <body> <p>My <span style='font-weight: bold'>favorite</span> kitchen item is the pan.</p> <p>A pan can also be used as a weapon.</p> <script> // walk the document body function walk (node) { // if text node if (node.nodeType == 3) { // will always be an element const parent = node.parentNode; // ignore script and style tags const tagName = parent.tagName; if (tagName !== 'SCRIPT' && tagName !== 'STYLE') { // wrap occurrences of 'pan' in a red `<span>` tag const span = '<span style="color: red">pan</span>'; parent.innerHTML = parent.innerHTML.replace (/pan/g, span) } } node = node.firstChild; while (node) { walk (node); node = node.nextSibling; } } walk (document.body) </script> </body> </html>
This code runs as intended most of the time. However, in this example, it doesn't. If you were to run this code, this would be the result.
I know what is causing this. However, I have no idea how to resolve it.
Two of the text nodes, My
and kitchen item is the pan.
have a parent element with the following innerHTML
: My <span style="font-weight: bold">favorite</span> kitchen item is the pan.
The "pan" in <span>
is being replaced, and is causing the problem.
If I use parentNode.textContent
instead of parentNode.innerHTML
, it does not wrap it in a <span>
tag, it inserts it as visible text.
I understand this could be fixed by changing /pan/g
to /\\bpan\\b/g
, but that only fixes this example I created. I need the <span>
tag to be only inserted into text content, and not tag names or other HTML.
What should I do?
Search a given htmlString
with an escaped search string. Doing so (with appropriate escaping) will help avoid problems like matching HTML tags (ex. <s
pan >
) or substrings (ex. Pan dora).
/* highlight(selector, string) @ Params: selector [String]: Same syntax as CSS/jQuery selector string [String]: Seach string */ // A: Get the htmlString of the target's content // B: Escape the search string // C: Create a RegExp Object of the escaped search string // D: Find and replace all matches with match wrapped in a <mark> // E: Remove original HTML // F: Insert new HTML function highlight(selector, string) { let dom = document.querySelector(selector); let str = dom.innerHTML; //A let esc = `(?!(?:[^<]+>|[^>]+<\\\\/a>))\\\\b(${string})\\\\b`; //B let rgx = new RegExp(esc, "gi"); //C let txt = str.replace(rgx, `<mark>$1</mark>`); //D dom.innerHTML = ''; //E dom.insertAdjacentHTML('beforeend', txt); //F } highlight('body', "pan");
<html> <body> <p>My <span style='font-weight: bold'>favorite</span> kitchen item is the pan.</p> <p>A pan can also be used as a weapon.</p> <p>Pan was the Greek god of the wild.</p> <p>Eboli was breifly a pandemic threat.</p> </body> </html>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.