简体   繁体   中英

How to wrap DOM keywords in a span tag

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM