新手技术问题:将p标签替换为span后,基于jQuery的文本高亮样式无法正常生效
Hey there, let's break down why your highlighting stopped working after switching from <p> to <span>, and fix it step by step!
What's Causing the Issue?
- Syntax Error in Your JS:The array passed to
hiliteWordsis missing a comma between'think'and'mojado'—this breaks the entire script before it even gets to the highlighting logic. - innerHTML Breaks Existing DOM Structure:When you overwrite the container's
innerHTML, you're destroying and re-creating all the original<span>tags. Your highlighting code wraps words in a new<span class="sketch-highlight">, which gets nested inside the existing inline-block spans, causing style conflicts and unexpected DOM behavior. - Word Boundary Matching Issues:The
\bregex boundary doesn't play well with HTML tags (like your<small>elements), so it might fail to match words that are wrapped in other tags.
Fixed Solution
We'll fix the syntax error, replace the destructive innerHTML approach with safe text-node traversal, and adjust styles to play nice with your inline-block spans.
Corrected JavaScript
$(document).ready(function() { // Process individual text nodes to avoid breaking existing DOM elements function hiliter(word, textNode) { var rgxp = new RegExp("\\b" + word + "\\b", 'gi'); var text = textNode.nodeValue; var matches = text.match(rgxp); if (!matches) return; var fragment = document.createDocumentFragment(); var lastIndex = 0; text.replace(rgxp, function(match, index) { // Add text before the matched word fragment.appendChild(document.createTextNode(text.slice(lastIndex, index))); // Create highlighted span for the match var highlightSpan = document.createElement('span'); highlightSpan.className = 'sketch-highlight'; highlightSpan.textContent = match; fragment.appendChild(highlightSpan); lastIndex = index + match.length; }); // Add any remaining text after the last match fragment.appendChild(document.createTextNode(text.slice(lastIndex))); // Replace original text node with our new fragment textNode.parentNode.replaceChild(fragment, textNode); } // Traverse only text nodes (skip existing spans to avoid re-processing) function traverseTextNodes(element, callback) { for (const node of element.childNodes) { if (node.nodeType === Node.TEXT_NODE && node.nodeValue.trim() !== '') { callback(node); } else if (node.nodeType === Node.ELEMENT_NODE && node.tagName !== 'SPAN') { traverseTextNodes(node, callback); } } } function hiliteWords(words, element) { words.forEach(word => { traverseTextNodes(element, textNode => hiliter(word, textNode)); }); } // Fixed array with missing comma hiliteWords(['creo','think', 'mojado','wet'], document.getElementById('subs')); });
Updated CSS
span { display: inline-block; padding: 8px; border: 0 solid white; background-color: white; font-size: 19px; line-height: 1.825; color: #000000; font-family: Nunito, sans-serif; } body { margin-left: 1px; margin-right: 1px; } .sketch-highlight { position: relative; display: inline; /* Keep highlight inline to not break layout */ } .sketch-highlight::before { content: ""; z-index: -1; left: 0em; top: 0em; border-width: 2px; border-style: solid; border-color: darkblue; position: absolute; border-right-color: transparent; width: 100%; height: 1em; transform: rotate(2deg); opacity: 0.5; border-radius: 0.25em; } .sketch-highlight::after { content: ""; z-index: -1; left: 0em; top: 0em; border-width: 2px; border-style: solid; border-color: darkblue; border-left-color: transparent; border-top-color: transparent; position: absolute; width: 100%; height: 1em; transform: rotate(-1deg); opacity: 0.5; border-radius: 0.25em; }
Cleaned-Up HTML
<!DOCTYPE html> <html> <head> <link rel="stylesheet" type="text/css" href="styles.css" /> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Nanum+Brush+Script&family=Nanum+Pen+Script&display=swap" rel="stylesheet"> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> </head> <body id='subs'> <center> <span><small>It was, it was. And then in an instant, it wasn't.</small><br>Pues sí, pues sí. Y luego, en un instante, se paró.</span> <span><small>- ¿Y por qué Jim no está mojado? - Yo… corrí más.</small><br>Why isn't Jim wet? I...outran it.</span> <span><small>No creo que haya llovido. Si no, me dolería la cadera.</small><br>I don't think it rained. My hip would be hurting.</span> </center> </body> </html>
Key Improvements
- Text Node Traversal: We only modify pure text content, so your original inline-block spans and
<small>tags stay intact. - Fixed Syntax: The missing comma in the words array is now added, so the script runs without errors.
- Layout-Friendly Highlighting: The
.sketch-highlightclass usesdisplay: inlineto avoid breaking your existing inline-block span layout.
内容的提问来源于stack exchange,提问作者chipsndip
相关产品推荐
相关产品推荐

