如何用JavaScript为字符串包裹HTML标签(修改页面数字字体)
问题:为页面数字包裹标签以修改字体(避免使用innerHTML)
需要修改页面中所有数字的字体,尝试过insertBefore()这类DOM方法但无法作用于字符串,也试过replace()替换数字但没达到预期效果,还尝试遍历数组分配元素却无法访问。希望能为所有数字包裹<span>或其他标签,且尽量不使用innerHTML。
解决方案:操作文本节点拆分重组
核心思路是遍历页面中的文本节点,将每个文本节点拆分为普通文本片段和数字片段,把数字片段用<span>包裹后重新插入DOM,全程避免直接使用innerHTML。
实现代码
HTML 结构
<!DOCTYPE html> <html lang="en"> <head> <style> body { text-align: center; font-size: 40px; } /* 给数字的span设置特殊字体样式 */ .digit-span { font-family: 'Courier New', monospace; color: #ff4444; } </style> </head> <body> <p> sdfjsdf (1): sdfdsdfs -- (1): sdfdsdfs -- (2) sdfsdf -- (3): sdfsdfs -- sdfdsfsdf -- </p> <script src="a.js"></script> </body> </html>
JavaScript 逻辑
// 递归遍历处理所有文本节点 function processTextNodes(node) { // 跳过非文本节点、script和style标签 if (node.nodeType !== Node.TEXT_NODE || node.parentNode.tagName === 'SCRIPT' || node.parentNode.tagName === 'STYLE') { if (node.hasChildNodes()) { Array.from(node.childNodes).forEach(child => processTextNodes(child)); } return; } const text = node.textContent; // 按连续数字拆分文本,保留数字片段 const parts = text.split(/(\d+)/); if (parts.length === 1) return; // 无数字,无需处理 // 创建文档片段,减少DOM操作次数 const fragment = document.createDocumentFragment(); parts.forEach(part => { if (/^\d+$/.test(part)) { // 数字部分用span包裹 const span = document.createElement('span'); span.className = 'digit-span'; span.textContent = part; fragment.appendChild(span); } else { // 普通文本直接创建文本节点 fragment.appendChild(document.createTextNode(part)); } }); // 替换原文本节点 node.parentNode.replaceChild(fragment, node); } // 从body开始处理所有节点 processTextNodes(document.body);
代码说明
- 遍历文本节点:递归遍历DOM树,精准定位需要处理的文本节点,跳过脚本、样式等无需修改的标签。
- 拆分文本内容:通过正则
/(\d+)/将文本拆分为普通文本和连续数字的片段,确保数字部分被单独提取。 - 构建文档片段:对每个片段做判断,数字片段生成带样式类的
<span>,普通文本生成原生文本节点,统一加入文档片段,减少DOM重排次数。 - 替换原节点:用文档片段替换原来的文本节点,完成数字的标签包裹。
内容的提问来源于stack exchange,提问作者user26545514
相关产品推荐
相关产品推荐

