如何为国际化(i18n)翻译内容添加局部样式?
原生JS下为i18n翻译文本添加局部样式的优雅方案
针对原生JS环境下给i18n翻译内容的局部片段添加粗体、颜色等样式的需求,这里提供一种比你提到的两种方案更灵活优雅的实现思路——通过自定义标记语法+JS解析渲染的方式,既保留单i18n键的简洁性,又能灵活调整样式,无需频繁修改代码逻辑。
实现思路
在i18n翻译文本中嵌入轻量的样式标记,标记格式类似简化版的markdown,但额外支持样式声明。然后编写一个原生JS函数,将带标记的文本解析成带样式的DOM元素片段,直接插入页面中。
具体步骤
定义i18n文本的标记规则
用**{样式声明}目标文本**的格式标记需要添加样式的部分,样式声明支持CSS键值对(多个样式用分号分隔)。以你的示例为例,翻译文本可以写成:All customer files **{color:yellow;font-weight:bold}must be authorized by the customer himself** , please be sure to invite the customer to scan this QR code.编写原生JS解析函数
这个函数会匹配标记内容,拆分普通文本和带样式的片段,创建对应的DOM节点并拼接成完整内容:// 解析带样式标记的i18n文本,返回可插入页面的DOM片段 function parseStyledI18nText(text) { const fragment = document.createDocumentFragment(); // 匹配标记规则:**{样式}内容**,非贪婪匹配避免跨段错误 const styleRegex = /\*\*{([^}]*)}\s*([^*]+?)\s*\*\*/g; let lastPosition = 0; let matchResult; while ((matchResult = styleRegex.exec(text)) !== null) { // 插入标记前的普通文本 if (matchResult.index > lastPosition) { fragment.appendChild(document.createTextNode(text.slice(lastPosition, matchResult.index))); } // 解析样式和目标内容 const styleProps = matchResult[1]; const styledContent = matchResult[2]; // 创建span容器并应用样式 const styledSpan = document.createElement('span'); styleProps.split(';').forEach(style => { const [prop, value] = style.split(':').map(item => item.trim()); if (prop && value) { styledSpan.style[prop] = value; } }); styledSpan.textContent = styledContent; fragment.appendChild(styledSpan); // 更新匹配起始位置 lastPosition = styleRegex.lastIndex; } // 插入剩余的普通文本 if (lastPosition < text.length) { fragment.appendChild(document.createTextNode(text.slice(lastPosition))); } return fragment; } // 实际使用示例 const translatedText = i18n.get('my-page.confim-customer.popup.warning'); // 假设i18n.get是你的翻译获取方法 const targetElement = document.getElementById('warning-popup'); targetElement.appendChild(parseStyledI18nText(translatedText));
方案优势
- 保留单个i18n键,无翻译文件冗余问题
- 样式调整只需修改i18n文本中的标记,无需改动JS代码逻辑,灵活性高
- 支持多样式组合,可轻松扩展斜体(
font-style:italic)、下划线(text-decoration:underline)等效果 - 纯原生JS实现,无任何框架依赖
注意事项
- 需告知翻译人员标记规则,避免误写;若文本中需要显示
**,可添加转义逻辑(比如先将\*\*替换为临时占位符,解析完成后再还原) - 解析函数可根据需求扩展,比如支持不同标记对应不同默认样式(比如用
__{内容}__表示斜体)
内容的提问来源于stack exchange,提问作者MiniScarabee
相关产品推荐
相关产品推荐

