h5+js传统项目多语言实现i18n

简介

大体思路是给每个文字标签设置一个自定义属性data-,再通过foreach 循环querySelectorAll获取的有这个属性的标签,标签,通过自定义属性的属性值去语言包中寻找对应的字段,最后通过textContent或者innerText来更新文字内容

实现

准备

en.json

{
    "locale": {
        "en": "English",
        "zh": "chainese"
    },
    "nav": {
        "home": "Home",
        "page1": "About Us",
        "zixun": "zixun"
    }
}

zh.json

{
    "locale": {
        "en": "英",
        "zh": "中"
    },
    "nav": {
        "home": "首页",
        "page1": "关于我们",
        "zixun": "资讯"
    }
}

具体语言包内容根据需要自行添加

看下我的目录结构
在这里插入图片描述

html

先看html
在标签中这样设置一个自定义属性data-translate=“nav.home”

 <li class="nav-system-home active">
         <a href="#" target="_self" data-translate="nav.home">首页</a> 
         <a href="#" target="_self" data-translate="nav.page1">关于我们</a>
  </li>
设置语言包、获取语言包字段

创建一个class类,里面是两个方法:设置语言包、获取语言包字段,
setLanguage:通过传入语言的不同来修改使用的语言包路径,
translate:传入的key是data-translate=""的属性值,通过这个属性值来找到对应的字段

class LanguageManager {

    async setLanguage(language) {
        const filePath = `../css/locale/${language}.json`;
        const response = await fetch(filePath);
        const data = await response.json();
        // console.log(data);
        this.translations = data;
    }

    translate(key) {
        const keyParts = key.split('.');
        const firstPart = keyParts[0]; // 'nav'
        const secondPart = keyParts[1]; // 'home'
        const translation = this.translations[firstPart][secondPart] || this.translations[key];
        return translation;
    }
}

const languageManager = new LanguageManager();
更新dom
function updateTranslations() {
    const elements = document.querySelectorAll('[data-translate]');//获取所有自定义属性为[data-translate]的标签
    elements.forEach(element => {//循环标签
        const key = element.getAttribute('data-translate');//获取data-translate的属性值
        const translation = languageManager.translate(key);//将key传给translate去获取对应的字段内容
        // console.log(123, translation);
        element.textContent = translation;//更新文字内容
    });
}
语言切换

//语言切换将需要设成的语言language传入

function changeLanguage(language) {
    languageManager.setLanguage(language).then(() => {
        updateTranslations();
    });
}
默认语言

//默认语言
function defaultLang() {
    const lang = localStorage.getItem('lang');
    //从本地缓存中获取默认语言,如果缓存中没有就去接口中获取,接口调用失败就用浏览器设置的语言
    // if (!lang) {
    //     fetch('/getdefaultLang').then(res => {
    //         localStorage.setItem('lang', res);
    //         changeLanguage('en')
    //     }).catch(err => {
    //         const browserLanguage = navigator.language || navigator.userLanguage;//获取浏览器默认语言
    //         changeLanguage(browserLanguage)
    //     })
    // } else {
    //     changeLanguage(lang)
    // }

    //测试、设为英文
    changeLanguage('en')
}
语言列表

考虑语言列表是从接口获取的,所以选择语言的select要写成动态渲染。
在这里插入图片描述在这里插入图片描述


//语言列表
function getLanguageList() {
  

    //新增select节点
    const addNewlang = (langList) => {
        const langList = ['en', 'zh'];//测试用暂时设置语言列表为 ['en', 'zh']
        const LangUl = document.getElementById('consultation-list');
        // console.log(LangUl);
        langList.forEach((item) => {//foreach语言列表,item为每一项
            var newParagraph = document.createElement('div') //创建一个div节点
            var node = document.createTextNode(item); //创建一个文本节点,文本内容为item
            newParagraph.appendChild(node);    //将文本节点插入刚创建的div节点
            newParagraph.classList.add('consultation-item'); //设置newParagraph节点的class样式
            newParagraph.setAttribute('data-translate', `locale.${item}`) 
             //为newParagraph节点添加data-translate属性,属性值为`locale.${item}`
            console.log(newParagraph);
            LangUl.appendChild(newParagraph);//将newParagraph节点插入到LangUl子节点列表的最后
            newParagraph.onclick = () => {//为newParagraph添加点击切换事件,
                changeLanguage(item)
            }
        });
    }
    addNewlang(langList) //测试
    //从接口中获取语言列表
    // let langList = localStorage.getItem('langList');
    if (!langList) {
        fetch('/#######').then(res => {
            localStorage.setItem('langList', res);
            //然后这里调用addNewlang     addNewlang(res) 
        }).catch(err => {
            const browserLanguage = navigator.language || navigator.userLanguage;//获取浏览器默认语言
            changeLanguage(browserLanguage)//切换语言为浏览器默认语言
        })
    }
}
//为防止找不到dom节点,在dom加载完后再执行获取语言列表和默认语言设置
window.onload = function () {
    getLanguageList()
    defaultLang()
}
locale.js
class LanguageManager {
    constructor() {
        this.translations = {};
        this.cache = new Map(); // 初始化缓存
    }

    async setLanguage(language) {
        // 检查语言文件是否已经在缓存中
        if (this.cache.has(language)) {
            this.translations = this.cache.get(language);
            return;
        }
        const filePath = `../css/locale/${language}.json`;
        try {
            const response = await fetch(filePath);
            if (!response.ok) {
                window.alert('网络似乎开小差了');
            }
            const data = await response.json();
            this.cache.set(language, data);// 将获取到的数据存入缓存
            this.translations = data;// 更新当前的 translations
        } catch (error) {
            window.alert('网络似乎开小差了');
            console.error(`Failed to fetch translation file: ${error}`);
            // 这里可以考虑使用默认语言或其他错误处理策略
        }
    }

    translate(key) {
        const keyParts = key.split('.');
        const firstPart = keyParts[0]; // 'nav'
        const secondPart = keyParts[1]; // 'home'
        const translation = this.translations[firstPart][secondPart] || this.translations[key];
        return translation;
    }
}

const languageManager = new LanguageManager();

function updateTranslations() {
    const elements = document.querySelectorAll('[data-translate]');
    elements.forEach(element => {
        const key = element.getAttribute('data-translate');
        const translation = languageManager.translate(key);
        // console.log(123, translation);
        element.textContent = translation;
    });
}
//语言切换
function changeLanguage(language) {
    languageManager.setLanguage(language).then(() => {
        updateTranslations();
    });
}
//默认语言
function defaultLang() {
    const lang = localStorage.getItem('lang');
    //从本地缓存中获取默认语言,如果缓存中没有就去接口中获取,接口调用失败就用浏览器设置的语言
    // if (!lang) {
    //     fetch('/getdefaultLang').then(res => {
    //         localStorage.setItem('lang', res);
    //         changeLanguage('en')
    //     }).catch(err => {
    //         const browserLanguage = navigator.language || navigator.userLanguage;//获取浏览器默认语言
    //         changeLanguage(browserLanguage)
    //     })
    // } else {
    //     changeLanguage(lang)
    // }

    //测试、设为英文
    changeLanguage('en')
}


//语言列表
function getLanguageList() {
    const langList = ['en', 'zh'];

    //新增select节点
    const addNewlang = (langList) => {
        const LangUl = document.getElementById('consultation-list');
        // console.log(LangUl);
        langList.forEach((item) => {
            var newParagraph = document.createElement('div')
            var node = document.createTextNode(item);
            newParagraph.appendChild(node);
            newParagraph.classList.add('consultation-item');
            newParagraph.setAttribute('data-translate', `locale.${item}`)
            console.log(newParagraph);
            LangUl.appendChild(newParagraph);
            newParagraph.onclick = () => {
                changeLanguage(item)
            }
        });
    }
    addNewlang(langList)
    //从接口中获取语言列表
    // let langList = localStorage.getItem('langList');
    if (!langList) {
        fetch('/#######').then(res => {
            localStorage.setItem('langList', res);
            //然后这里调用addNewlang
        }).catch(err => {
            const browserLanguage = navigator.language || navigator.userLanguage;//获取浏览器默认语言
            changeLanguage(browserLanguage)
        })
    }

}


window.onload = function () {
    getLanguageList()
    defaultLang()
}
  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
H5是指HTML5,是一种用于构建和呈现Web页面的标准化技术。它提供了很多新特性和功能,包括更丰富的媒体操作,地理定位,离线应用等。通过使用H5开发人员可以更加灵活和高效地开发Web应用程序。 JS指的是JavaScript,是一种脚本语言,广泛用于Web开发中。它能够与HTML和CSS一起,用于实现页面的交互和动态效果。使用JS开发人员可以实现一些复杂的功能,包括表单验证,数据操作,动画效果等。 .NET Framework是微软公司开发的应用程序开发平台,用于构建应用程序和Web服务。它提供了广泛的功能和库,包括安全性,数据访问,图形操作等。开发人员可以使用.NET Framework来开发各种类型的应用程序,包括桌面应用程序,Web应用程序和移动应用程序。 开发技术文档是为了方便其他开发人员理解和使用相关技术而编写的文档。在H5JS和.NET Framework开发技术文档中,可能包含以下内容: 1. 技术概述:介绍H5JS和.NET Framework的基本概念和特点。 2. 环境搭建:包括安装和配置开发环境的步骤,例如安装相关的开发工具和平台。 3. 开发指南:提供关于如何使用H5JS和.NET Framework开发应用程序的详细指导,包括语法,API文档和示例代码等。 4. 工具和资源:介绍一些有用的开发工具和资源,例如调试器,集成开发环境和开发者社区等。 5. 常见问题解答:列出一些常见的问题和解决方法,帮助开发人员解决开发过程中可能遇到的问题。 总之,H5JS和.NET Framework开发技术文档是开发人员进行相关技术开发时的重要参考资料,它们提供了详细的技术信息和指导,帮助开发人员更好地理解和应用这些技术。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值