You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

新手技术问题:将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?

  1. Syntax Error in Your JS:The array passed to hiliteWords is missing a comma between 'think' and 'mojado'—this breaks the entire script before it even gets to the highlighting logic.
  2. 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.
  3. Word Boundary Matching Issues:The \b regex 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&amp;family=Nanum+Pen+Script&amp;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-highlight class uses display: inline to avoid breaking your existing inline-block span layout.

内容的提问来源于stack exchange,提问作者chipsndip

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 17:54:05