如何用Vanilla JavaScript在HTML页面多元素中搜索并高亮文本
实现多元素文本搜索高亮(Vanilla JavaScript方案)
下面是一套纯JS实现的多元素文本搜索高亮方案,支持页面中任意数量的文本元素,同时避免破坏原有DOM结构:
完整代码示例
HTML 部分
<div> <input type="text" placeholder="Search..." id="searchInput"> </div> <!-- 示例多文本元素 --> <p>这是第一段测试文本,包含要搜索的关键词。</p> <div class="content">第二段文本,可能嵌套<span>其他元素</span>,依然能正确高亮关键词。</div> <p>第三段文本,支持大小写不敏感搜索。</p>
JavaScript 部分
const searchInput = document.getElementById('searchInput'); // 监听输入事件实现实时搜索(也可替换为blur事件:searchInput.addEventListener('blur', search)) searchInput.addEventListener('input', search); // 清除所有高亮标记 function removeHighlights() { const highlights = document.querySelectorAll('.search-highlight'); highlights.forEach(highlight => { const parent = highlight.parentNode; parent.replaceChild(document.createTextNode(highlight.textContent), highlight); parent.normalize(); }); } // 核心搜索高亮逻辑 function search() { const query = searchInput.value.trim(); // 清空搜索框时移除所有高亮 if (!query) { removeHighlights(); return; } // 转义正则特殊字符,避免注入风险 const escapedQuery = query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // 创建全局、大小写不敏感的正则规则 const regex = new RegExp(`(${escapedQuery})`, 'gi'); // 遍历目标文本元素(可自定义选择器,比如只筛选.content类元素) const textElements = document.querySelectorAll('p, div.content'); textElements.forEach(element => { // 递归遍历元素内的所有文本节点 traverseTextNodes(element, regex); }); } // 递归处理文本节点,避免破坏原有DOM结构 function traverseTextNodes(element, regex) { const childNodes = Array.from(element.childNodes); childNodes.forEach(node => { // 仅处理纯文本节点 if (node.nodeType === Node.TEXT_NODE && node.textContent.trim()) { const matches = node.textContent.match(regex); if (matches) { const fragment = document.createDocumentFragment(); let lastIndex = 0; node.textContent.replace(regex, (match, group, index) => { // 添加匹配区间之前的文本 if (index > lastIndex) { fragment.appendChild(document.createTextNode(node.textContent.slice(lastIndex, index))); } // 创建高亮span标签 const highlight = document.createElement('span'); highlight.className = 'search-highlight'; highlight.textContent = match; fragment.appendChild(highlight); lastIndex = index + match.length; }); // 添加剩余未匹配的文本 if (lastIndex < node.textContent.length) { fragment.appendChild(document.createTextNode(node.textContent.slice(lastIndex))); } // 替换原文本节点 element.replaceChild(fragment, node); } } else if (node.nodeType === Node.ELEMENT_NODE && !node.classList.contains('search-highlight')) { // 递归处理子元素,跳过已高亮的span标签 traverseTextNodes(node, regex); } }); }
CSS 高亮样式
.search-highlight { background-color: #ffeb3b; font-weight: bold; }
关键特性说明
- 多元素适配:通过
querySelectorAll可指定任意需要搜索的元素集合,覆盖页面中多个文本区块。 - DOM结构安全:仅递归处理纯文本节点,不会破坏原有的嵌套元素(如链接、自定义span等)。
- 正则安全:对搜索关键词做特殊字符转义,避免正则表达式注入问题。
- 灵活触发:默认实时搜索,可根据需求切换为失焦触发。
- 大小写兼容:正则规则支持大小写不敏感匹配。
内容的提问来源于stack exchange,提问作者Yazan
相关产品推荐
相关产品推荐

