介绍
常见的产品介绍性的网站一般为静态网站,如果要实现产品的国际化,需要对网站进行多语言设置,可以自动识别当前浏览器的语言并更换适配的语言,并且用户可以手动选择语言类型实现语言切换。
以下以一个静态的Bootstrap网站为例介绍多语言切换的实现。
静态网站模板网站:https://bootstrapmade.com/
实现效果如下,可以在浏览器的设置中设置首选语言来查看效果。
英文效果:
中文效果:
实现流程
下载一个静态网站,目录结构如下,其中红色方框的内容是本次改造新增的文件。
本文以改造导航栏的多语言为例。
(1)首先在index.html
中找到导航栏的代码,给每个导航菜单加上id
属性,并给选择语言的下拉框中每个语言a
标签添加data-lang
属性,用于在点击时传递对于的语言类型,可以自定义。
<nav id="navmenu" class="navmenu">
<ul>
<li><a id="nav-home" href="#hero" class="active">Home</a></li>
<li><a id="nav-about" href="#about">About</a></li>
<li><a id="nav-services" href="#services">Services</a></li>
<li><a id="nav-portfolio" href="#portfolio">Portfolio</a></li>
<li><a id="nav-team" href="#team">Team</a></li>
<li><a id="nav-pricing" href="#pricing">Pricing</a></li>
<li><a id="nav-contact" href="#contact">Contact</a></li>
<li class="dropdown"><a id="nav-language" href="#"><span>Language</span> <i class="bi bi-chevron-down toggle-dropdown"></i></a>
<ul>
<li><a href="#" data-lang="en">English</a></li>
<li><a href="#" data-lang="zh">中文简体</a></li>
</ul>
</li>
</ul>
<i class="mobile-nav-toggle d-xl-none bi bi-list"></i>
</nav>
(2)实现多语言切换主要使用的是i18next
功能插件(https://www.i18next.com/),在index.html
的底部JS依赖中引入i18next
和i18next-http-backend
,其中前者是实现语言切换的库,后者是可以从本地JSON文件读取语言配置文件的插件。i18next
需要手动初始化,代码可以放在language.js
,并引入到index.html
。
<!-- locales -->
<script src="https://unpkg.com/i18next@21.8.15/dist/umd/i18next.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/i18next-http-backend@2.5.2/i18nextHttpBackend.min.js"></script>
<script src="assets/js/language.js"></script>
(3)language.js
的代码如下:
先初始化i18next
, navigator.language
返回的是当前首选语言的英文缩写,如zh-CN,因为当前网站只打算支持中文和英文,因此不关心国家代码,只区分语言如en或zh,关于navigator.language
的更多介绍参考:https://developer.mozilla.org/zh-CN/docs/Web/API/Navigator/language。
updateContent
是读取语言JSON文件中所有的key,这些key是HTML页面中的元素ID值,把语言文件中定义的值更新到页面中。如果页面中有重复的内容,则可以设置该元素的name值为动态变量,JS代码根据name值来获取对应的元素列表,并循环更新元素值。
最后添加了一个监听器监听页面内容加载,并且监听语言切换按钮,如用户主动切换语言,则刷新页面内容。
代码语言:javascript复制i18next.use(i18nextHttpBackend).init({
lng: getLanguage(),
backend: {
loadPath: '/assets/locales/{{lng}}.json'
}
}, function(err, t) {
updateContent(); // 确保在文档加载后调用
});
function getLanguage(){
return navigator.language.split("-")[0]; // 只区分语言,不区分地区
}
function updateContent() {
fetch(`/assets/locales/${getLanguage()}.json`)
.then(response => response.json())
.then(data => {
for (const key in data) {
// document.getElementById(key).textContent = i18next.t(key);
let element = document.getElementById(key);
if(element === undefined || element == null){
let elements = document.getElementsByName(key)
if(elements === undefined || elements == null || elements.length === 0){
continue
}
for (let i = 0; i < elements.length; i ) {
elements[i].textContent = i18next.t(key);
}
}else {
element.textContent = i18next.t(key);
}
}
})
.catch(error => {
console.error('Error reading JSON file:', error);
});
}
document.addEventListener('DOMContentLoaded', function() {
var languageLinks = document.querySelectorAll('a[data-lang]');
languageLinks.forEach(function(link) {
link.addEventListener('click', function(event) {
event.preventDefault(); // 阻止链接默认行为
var selectedLang = this.getAttribute('data-lang');
console.log('selectedLang:', selectedLang)
i18next.changeLanguage(selectedLang, function(err, t) {
if (err) return console.error('Something went wrong loading', err);
updateContent(); // 更新页面内容的函数
});
});
});
});
(4)语言JSON文件示例如下,其中的key需要和HTML页面中定义的元素ID一致。
en.json
代码语言:javascript复制{
"nav-home": "Home",
"nav-about": "About",
"nav-services": "Services",
"nav-portfolio": "Portfolio",
"nav-team": "Team",
"nav-pricing": "Pricing",
"nav-contact": "Contact",
"nav-language": "Language"
}
zh.json
代码语言:javascript复制{
"nav-home": "首页",
"nav-about": "关于我们",
"nav-services": "服务",
"nav-portfolio": "作品集",
"nav-team": "团队",
"nav-pricing": "价格",
"nav-contact": "联系我们",
"nav-language": "语言"
}
其中文件夹下的dev.json是一个空的json文件,前端浏览器默认会请求该文件,否则会报错找不到该文件,但不影响使用,为了消除该错误,可以建一个空的json文件。