不使用jQuery 纯JS实现指定类p元素中匹配数组的单词包裹b标签
原生JavaScript实现方案
核心思路
- 先匹配所有指定类名的
<p>元素 - 将待匹配单词数组转成带单词边界的全局正则,同时转义特殊字符避免正则语法错误
- 对目标元素的文本内容做匹配替换,将命中的单词用
<b>标签包裹
基础实现(适用于目标<p>内仅含纯文本的场景)
该写法简单直接,适配题目给出的示例场景:
const words = ["Hello", "World", "Text"]; // 转义正则特殊字符,避免单词含特殊字符时匹配异常 const escapeRegExp = str => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // 生成全局匹配正则,\b 保证只匹配完整独立单词 const matchReg = new RegExp(`\\b(${words.map(escapeRegExp).join('|')})\\b`, 'g'); // 遍历所有目标p元素执行替换 document.querySelectorAll('p.codeText').forEach(pEl => { pEl.innerHTML = pEl.textContent.replace(matchReg, '<b>$1</b>'); });
执行后示例中的<p>元素会变为:
<p class="codeText"><b>Hello</b> <b>World</b>, this <b>Text</b> say <b>Hello</b> <b>World</b></p>
兼容复杂DOM的实现(适用于目标<p>内含其他嵌套标签的场景)
如果目标<p>内有其他子元素或绑定了事件,用上述innerHTML替换会破坏原有DOM结构和事件绑定,可使用递归处理文本节点的方案:
const words = ["Hello", "World", "Text"]; const escapeRegExp = str => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); const matchReg = new RegExp(`\\b(${words.map(escapeRegExp).join('|')})\\b`, 'g'); // 递归处理文本节点 const wrapMatchedWord = node => { // 仅处理文本节点 if (node.nodeType === Node.TEXT_NODE) { const text = node.textContent; if (!matchReg.test(text)) return; const fragment = document.createDocumentFragment(); let lastIndex = 0; let match; // 遍历所有匹配结果拆分节点 while ((match = matchReg.exec(text)) !== null) { if (match.index > lastIndex) { fragment.appendChild(document.createTextNode(text.slice(lastIndex, match.index))); } const bTag = document.createElement('b'); bTag.textContent = match[0]; fragment.appendChild(bTag); lastIndex = matchReg.lastIndex; } if (lastIndex < text.length) { fragment.appendChild(document.createTextNode(text.slice(lastIndex))); } node.parentNode.replaceChild(fragment, node); return; } // 元素节点递归处理子节点,跳过已包裹的b标签避免重复匹配 if (node.nodeType === Node.ELEMENT_NODE && node.tagName !== 'B') { Array.from(node.childNodes).forEach(wrapMatchedWord); } } // 遍历所有目标p元素 document.querySelectorAll('p.codeText').forEach(pEl => { Array.from(pEl.childNodes).forEach(wrapMatchedWord); });
内容的提问来源于stack exchange,提问作者user16262715
相关产品推荐
相关产品推荐

