多语言站点:自定义谷歌翻译功能
如果你正在开发一个多语言网站,又不打算自行管理多语言内容,可以参考下面的步骤,简便地引入第三方谷歌翻译功能,同时避免 Google 翻译那个“巨大的蓝色工具栏”破坏页面设计。
1. 核心原理
Google 翻译脚本的工作方式是寻找特定的 Cookie googtrans。当我们手动改变这个 Cookie 并触发页面上的隐藏下拉框(.goog-te-combo)的 change 事件时,Google 的引擎就会开始工作。
2. 实现步骤
准备 HTML 容器
你需要两个东西:
- 自定义 UI:一个按钮或图标,加上一个原生的
<select>菜单。 - 存根元素:一个 id 为
google_translate_element的空 div。Google 会在这里渲染它“丑陋”的原始组件,但我们会用 CSS 把它藏起来。
引入 Google 核心脚本
在 body 结束前引入:
<script src="https://translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"></script>
这里的 cb=... 是回调函数名,确保它与你 JS 中的初始化函数名一致。
编写 JS 控制逻辑(重点)
你的脚本需要完成三件事:
- 初始化:告诉 Google 你的默认语言和目标语言。
- 写入 Cookie:设置过期时间很长的 Cookie,这样用户下次访问时页面依然是翻译过的。
- 分发事件:通过
dispatchEvent(new Event("change"))告诉 Google 的脚本:“嘿,用户选了新语言,快干活!”
CSS 魔改(成败关键)
Google 翻译加载后会强制修改你的 HTML 结构,比如:
- 给
<html>标签添加top: 40px。 - 在页面顶部插入一个 iframe 工具栏。
- 给翻译后的文字包裹
<font>标签并加高亮。
务必使用 !important 策略:在你的 CSS 文件中像我上面代码那样,强制将 top 设为 0,并把 .goog-te-banner-frame 设为 display: none。
3. 完整参考代码
<div class="container d-flex justify-content-between align-items-center py-3">
<div class="footer-block d-flex align-items-center gap-3">
<div style="position: relative; display: inline-flex; align-items: center;">
<img
id="lang-toggle-icon"
src="/assets/img/translate.svg"
alt="Language"
style="width: 40px; height: 40px; cursor: pointer; opacity: 0.8; transition: opacity 0.2s;"
onmouseover="this.style.opacity=1"
onmouseout="this.style.opacity=0.8"
/>
<div
id="gt-wrapper"
style="
display: none;
position: absolute;
top: 0; /* 位于图标顶部 */
left: 100%; /* 位于图标右侧 */
transform: translateX(-100%); /* 确保从左侧弹出 */
z-index: 10000;
background: white;
padding: 5px;
border-radius: 6px;
box-shadow: 0 4px 15px rgba(0,0,0,0.2);
white-space: nowrap;
"
>
<select id="language-select" style="font-size:1rem; padding:4px; border: 1px solid #ddd; border-radius: 4px; outline: none; cursor: pointer;">
<optgroup label="Official">
<option value="zh-CN">中文</option>
<option value="en">English</option>
<option value="fr">Français</option>
<option value="es">Español</option>
<option value="ar">العربية</option>
<option value="ru">Русский</option>
</optgroup>
<optgroup label="Population > 50M">
<option value="hi">हिन्दी</option>
<option value="bn">বাংলা</option>
<option value="pt">Português</option>
<option value="id">Bahasa Indonesia</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
<option value="vi">Tiếng Việt</option>
<option value="th">ไทย</option>
</optgroup>
</select>
</div>
</div>
</div>
</div>
<div id="google_translate_element" style="position: absolute; top: 0; left: 0; width: 0; height: 0; overflow: hidden; display: none;"></div>
<script src="https://translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"></script>
<script>
/* --- 模块 1: 悬浮框交互逻辑 --- */
(function () {
const icon = document.getElementById("lang-toggle-icon");
const wrapper = document.getElementById("gt-wrapper");
if (icon && wrapper) {
// 点击图标切换菜单显示/隐藏
icon.addEventListener("click", function (e) {
e.stopPropagation();
const isVisible = wrapper.style.display === "block";
wrapper.style.display = isVisible ? "none" : "block";
});
// 点击页面其他地方关闭菜单
document.addEventListener("click", function (e) {
if (!wrapper.contains(e.target) && e.target !== icon) {
wrapper.style.display = "none";
}
});
}
})();
/* --- 模块 2: Google Translate 初始化 --- */
function googleTranslateElementInit() {
new google.translate.TranslateElement(
{
pageLanguage: "zh-CN", // 网站默认语言
includedLanguages: "zh-CN,en,fr,es,ar,ru,hi,bn,pt,id,ja,ko,vi,th", // 允许翻译的语言列表
autoDisplay: false, // 禁止自动弹出原始工具栏
},
"google_translate_element"
);
}
// 设置持久化 Cookie
function setCookie(name, value) {
document.cookie = name + "=" + value + "; path=/; expires=Fri, 31 Dec 9999 23:59:59 GMT";
}
/* --- 模块 3: 核心翻译应用逻辑 --- */
function applyLang(lang) {
// 设置 Google 翻译所需的 Cookie 格式:/源语言/目标语言
setCookie("googtrans", "/auto/" + lang);
setCookie("googtrans", "/zh-CN/" + lang);
localStorage.setItem("gt_lang", lang);
document.documentElement.lang = lang;
// 核心操作:模拟操作 Google 原始的选择框以触发翻译
const combo = document.querySelector(".goog-te-combo");
if (combo) {
combo.value = lang;
combo.dispatchEvent(new Event("change"));
}
}
const select = document.getElementById("language-select");
// 初始化时读取已有的翻译 Cookie
const cookieLang = (function () {
const match = document.cookie.match(/googtrans=\/[a-zA-Z\-]+\/([a-zA-Z\-]+)/);
return match ? match[1] : null;
})();
if (select) {
const initialLang = cookieLang || "zh-CN";
select.value = initialLang;
// 监听自定义下拉菜单的变化
select.addEventListener("change", function () {
applyLang(this.value);
document.getElementById("gt-wrapper").style.display = "none"; // 选择后关闭
});
}
/* --- 模块 4: 状态同步 --- */
// 确保当 Google 脚本加载完成并生成 .goog-te-combo 后,同步一次状态
function syncTranslateCombo() {
const combo = document.querySelector(".goog-te-combo");
if (combo && select) {
combo.value = select.value;
combo.dispatchEvent(new Event("change"));
} else {
setTimeout(syncTranslateCombo, 500); // 递归查找直到加载成功
}
}
syncTranslateCombo();
</script>
<style>
/* --- 关键修复:防止页面整体偏移 --- */
/* 强制重置 html 和 body 的 top 属性,对抗 Google 的自动插入 */
html,
body {
top: 0 !important;
position: static !important;
min-height: auto !important;
margin-top: 0 !important;
}
/* 彻底隐藏 Google 的顶部横幅 */
.goog-te-banner-frame,
iframe.goog-te-banner-frame,
.goog-te-banner-frame.skiptranslate,
.skiptranslate,
.goog-tooltip,
.goog-tooltip:hover {
display: none !important;
visibility: hidden !important;
height: 0 !important;
width: 0 !important;
}
/* 隐藏页面中可能出现的 Google 浮标图标 */
.goog-te-gadget-icon {
display: none !important;
}
/* 隐藏鼠标悬停时的提示弹窗 */
.goog-tooltip,
.goog-tooltip:hover {
display: none !important;
}
/* 移除翻译后的文字高亮样式 */
.goog-text-highlight {
background: none !important;
box-shadow: none !important;
}
/* 修复 Google 翻译注入的 font 标签导致的行高变化 */
font {
background-color: transparent !important;
box-shadow: none !important;
box-sizing: content-box !important;
}
</style>
4. 注意事项
- 本地测试:Google 翻译在 localhost 或 127.0.0.1 有时会失效,建议在正式域名或内网穿透环境下测试。
- 网速延迟:Google 脚本从海外加载,可能会有 1-2 秒的延迟。你可以加一个 Loading 动画,等
syncTranslateCombo完成后再隐藏。 - SEO 提示:这种翻译是客户端行为,搜索引擎爬虫(如 Googlebot)看到的依然是你的原始语言。