jQuery使用i18n国际化插件实现双语网站,如何解决页面跳转时出现的短暂复原情况

发布于 2022-09-12 03:41:27 字数 6082 浏览 39 评论 0

项目环境:bootstrap框架,jQuery库(目前对前端这些名词还不是很清楚,但是项目比较简单,纯前端页面,没有后端)


问题背景:原项目是中文网页,图片较多加载比较缓慢,已经采用了懒加载,但是还是会加载三四秒才会结束。现在希望实现双语网站,我使用了i18n国际化插件,下图是我的目录
9%3_0G[G${HUY2$T7{VHLX1.png
en、ja、zh分别存储三种语言的翻译内容,language.js里面包含了cookie操作、获取浏览器本地语言、根据用户的选择切换相应的语言内容,language.js的代码如下:

/* cookie存储用户选取的值 */
function setCookie (name, value)
{ 
    /* 设置名称为name,值为value的Cookie */
    var expdate = new Date();
    /* 计算时间,30天后过期 */
    expdate.setTime(expdate.getTime() + 30 * 24 * 60 * 60 * 1000);
    document.cookie = name + "=" + value + "; expires=" + expdate.toGMTString() + "; path=/";
   /* 即document.cookie= name+"="+value+";path=/";   时间可以不要,但路径(path)必须要填写,因为JS的默认路径是当前页,如果不填,此cookie只在当前页面生效! */
}

/* 获取cookie */
function getCookie(name)
{
    if (document.cookie.length > 0)
        {
            start = document.cookie.indexOf(name + "=")
            if (start != -1)
                { 
                start = start + name.length + 1 
                end = document.cookie.indexOf(";", start)
                if (end == -1) end = document.cookie.length
                return unescape(document.cookie.substring(start, end))
                } 
        }
    return ""
}

/**
 * 获取浏览器本地语言类型
 * @return {string}
 */
var getNavLanguage = function(){
    if(navigator.appName == "Netscape"){
        var navLanguage = navigator.language;
        return navLanguage.substr(0,2);
    }
    return false;
}

/**
 * 设置语言类型: 默认为中文
 */
var i18nLanguage = "zh";

/*
设置网站支持的语言种类
 */
var webLanguage = ['zh', 'en', 'ja'];

/**
 * 执行页面i18n方法,初始化阶段
 * @return
 */ 
var execI18n = function(){
    /*
    获取一下资源文件名
     */
    var optionEle = $("#i18n_pagename");
    if (optionEle.length < 1) {
        console.log("未找到页面名称元素,请在页面写入\n <meta id=\"i18n_pagename\" content=\"页面名(对应语言包的语言文件名)\">");
        return false;
    };

    var sourceName = optionEle.attr('content');
    sourceName = sourceName.split('-');

    /* 首先获取用户选择过的语言 */ 
    if (getCookie('userLanguage')) {
        i18nLanguage = getCookie('userLanguage')
    } else {
        /* 否则使用浏览器默认语言 */
        var navLanguage = getNavLanguage();
        console.log('浏览器语言', navLanguage)
        if (navLanguage) {
            /* 判断是否在网站支持语言数组里 */
            var charSize = $.inArray(navLanguage, webLanguage);
            if (charSize > -1) {
                i18nLanguage = navLanguage;
            };
        } else{
            console.log("not navigator");
            return false;
        }
    }
        

    /* 引入 i18n 文件*/
    if ($.i18n == undefined) {
        console.log("请引入i18n js 文件")
        return false;
    };

    /*
    这里需要进行i18n的翻译
        */
    jQuery.i18n.properties({
        name : sourceName, //资源文件名称,上面已经定义过
        path : 'i18n/' + i18nLanguage +'/', //资源文件路径,存放字段值的文件路径
        mode : 'map', //用Map的方式使用资源文件中的值
        language : i18nLanguage,
        callback : function() {//加载成功后设置显示内容
            var insertEle = $(".i18n");
            console.log(".i18n 写入中...");
            insertEle.each(function() {
                // 根据i18n元素的 name 获取内容写入
                $(this).html($.i18n.prop($(this).attr('name')));
            });
            console.log("写入完毕");

            /* console.log(".i18n-input 写入中...");
            var insertInputEle = $(".i18n-input");
            insertInputEle.each(function() {
                var selectAttr = $(this).attr('selectattr');
                if (!selectAttr) {
                    selectAttr = "value";
                };
                $(this).attr(selectAttr, $.i18n.prop($(this).attr('selectname')));
            });
            console.log("写入完毕"); */
        }
    });
}

/* 切换语言后,重新获取语言内容并写入页面 */
var updateI18n = function(){
    /*
    获取一下资源文件名
     */
    var optionEle = $("#i18n_pagename");
    if (optionEle.length < 1) {
        console.log("未找到页面名称元素,请在页面写入\n <meta id=\"i18n_pagename\" content=\"页面名(对应语言包的语言文件名)\">");
        return false;
    };
    var sourceName = optionEle.attr('content');
    sourceName = sourceName.split('-');
    
    /* 需要引入 i18n 文件*/
    if ($.i18n == undefined) {
        console.log("请引入i18n js 文件")
        return false;
    };

    /*
    这里需要进行i18n的翻译
        */
    jQuery.i18n.properties({
        name : sourceName, //资源文件名称
        path : 'i18n/' + i18nLanguage +'/', //资源文件路径
        mode : 'map', //用Map的方式使用资源文件中的值
        language : i18nLanguage,
        callback : function() {//加载成功后设置显示内容
            var insertEle = $(".i18n");
            console.log(".i18n 写入中...");
            insertEle.each(function() {
                // 根据i18n元素的 name 获取内容写入
                $(this).html($.i18n.prop($(this).attr('name')));
            });
            console.log("写入完毕");
        }
    });
}

/*页面加载执行*/
$(function(){

    /*执行I18n翻译*/
    execI18n();

    /* 切换到汉语 */
    $("#toChinese").click(function () {
        i18nLanguage = "zh"
        setCookie('userLanguage', i18nLanguage)
        updateI18n()
    })

    /* 切换到英语 */
    $("#toEnglish").click(function () {
        i18nLanguage = "en"
        setCookie('userLanguage', i18nLanguage)
        updateI18n()
    })

    /* 切换到日语 */
    $("#toJapanese").click(function () {
        i18nLanguage = "ja"
        setCookie('userLanguage', i18nLanguage)
        updateI18n()
    })
});

在项目的每个HTML文件中引入了该js文件。


在浏览器中语言能够成功切换,也能够将用户选择的语言存入cookie,并能够在用户下次进入该页面时自动切换。
我的问题:因为页面加载时,会先等页面组件都加载完毕,才会使用这个js文件去对相应组件的内容进行更换,前面提到页面加载较慢,因此加载的这两三秒中,会出现短暂的HTML文件设置好的文本,然后再更换为识别出的语言。
假设页面有一个按钮,html代码写的文本为“注册”,我们点击语言切换按钮选择了英文,这个按钮也成功切换成了“sign up”,此时浏览器的cookie会保存我们选择的语言“en”,所以我们刷新这个页面,js文件获取到的语言类型为英语,但是刷新页面的时候,js也会重新加载,所以加载的两三秒时间里,按钮的文本会显示html代码中的“注册”,加载完之后会自动更换为“sign up”,我不希望出现这个短暂的“注册”。我们从这个页面跳转到别的页面时也会出现同样的情况,新页面的内容先显示html代码中的中文文本,页面加载完再被替换成英文。如果去掉html代码中的文本,加载时组件内容为空,页面加载完后会自动渲染上翻译文件里面的内容,我也不想让它加载的时候为空所以想问问有没有前辈知道怎么解决这个加载缓慢带来的短暂时间内内容不一致的问题
感激不尽!
(其实在某一个页面切换语言时,整个项目的页面内容都被切换了,但是跳转到一个新的页面时,这个页面还是会重新加载,js也会重新加载,和刷新页面是一样的道理)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

以为你会在 2022-09-19 03:41:27

如果纯客户端的解决方案,貌似只能做到这样吧.都是先显示模本原始语言,js运行后,才会切换成设置的语言.

要求高的话,i18n 就交给后端来处理,但是你的项目又没有后端,那你只能调整下加载顺序,让 i18n 的逻辑最先加载,最先运行,不要在加载阶段被别的东西堵塞了.

樱&纷飞 2022-09-19 03:41:27

1.script 标签内联了解一下
2.配置初始化状态 install, 默认 loading 图片用起来 ... 内容没有加载成功的时候放这个,
加载成功,更新状态,更新 $dom 的样式,取消loading

萌能量女王 2022-09-19 03:41:27

切换语言这种,一般都是加loading处理。
很有名的插件jQuery remodal https://vodkabears.github.io/...

比如Vue.js 也是需要使用 [v-cloak] { display: none } ,可以隐藏未编译的 Mustache 标签直到实例准备完毕

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文