jQuery实现的前端多语言解决方案
发表时间: 2019-01-22 10:01
话不多说,还是先看看效果图吧:
如图所示,通过改变地址栏 local 的值即可切换语言,下面我贴一下具体的代码:
<div> <span class="ch-i18n" data-i18nkey="today">今天</span></div><div> <input type="text" class="ch-i18n" data-i18nkey="emailLabel" placeholder="请输入邮箱"></div><div> <input type="submit" class="ch-i18n" data-i18nkey="submit" value="提交"></div><div> <label> <input type="radio"><span class="ch-i18n" data-i18nkey="man">男</span> </label> <label> <input type="radio"><span class="ch-i18n" data-i18nkey="woman">女</span> </label></div><div> <label> <input type="checkbox"><span class="ch-i18n" data-i18nkey="apple">苹果</span> </label> <label> <input type="checkbox"><span class="ch-i18n" data-i18nkey="banana">香蕉</span> </label></div><div id="insert"></div><input type="button" id="btn1" class="ch-i18n" data-i18nkey="button" value="插入HTML"><div id="placeholder"></div><input type="button" id="btn2" value="替换文本中的占位符"><script src="./js/jquery-1.8.1.js"></script><script src="./js/i18n.js"></script><script> $(function () { var chI18n = CHI18n("login"); // 动态插入数据 $("#btn1").click(function () { $("#warning").show(); $("#insert").html('<span>'+chI18n.get("insert")+'</span>'); }); $("#btn2").click(function () { $("#placeholder").html(chI18n.get("msg" , {name:'king',age:24,sex:'男'})); }); })</script>
如代码所示,需要国际化的标签,需要注意下面这几点:
{ "login":{ "today":"今天", "submit":"提交", "emailLabel":"请输入邮箱", "apple":"苹果", "banana":"香蕉", "woman":"女", "man":"男", "button":"按钮", "insert":"动态插入信息", "msg":"我叫{{name}},今年{{age}}岁,性别{{sex}}" }}
这是我们一个简单的国际化语言文件的格式(英文的跟这个一样,我就不贴出来了),我们通过 data-i18nkey 属性绑定这些 key ,然后 i18n.js 就能自动去解析,并显示每个标签所需要显示的文本。
(function () { var i18n = null ; var SELECTOR = ".ch-i18n"; var ATTR = "data-i18nkey"; var LANGUAGE_ARRAY = ['zh-cn','en-us']; var lang = LANGUAGE_ARRAY[0]; var LOCAL = "local"; var CHI18n = { get : function (key , obj) { var text = i18n[key] ; if(obj) { for(k in obj) { text = text.replace(new RegExp("\{\{" + k + "\}\}", "g"), obj[k]); } } return text ; } } // 我这里根据页面为单位,通过页面的唯一标识,去获取相应的国际化翻译 function CHI18nFactory (pageName) { if(!pageName || pageName == "") throw new Error("参数不能为空"); loadLanguage(pageName); return CHI18n ; } /** * 加载语言文件 */ function loadLanguage (pageName) { var search = window.location.search.replace("?",""); var param = search.split("&"); var index = param.findIndex(function (item) { return item.indexOf(LOCAL) != -1 ; }); if(index != -1) { var value = param[index].replace(LOCAL+"=",""); if(LANGUAGE_ARRAY.indexOf(value) != -1) { lang = value ; } } // 加载国际化文本 $.ajax({ url:'./i18n/'+lang+'.json', async:false, dataType:'json', success:function (data) { i18n = data[pageName] ; setLanguage(); } }); } /** * 替换带有 .ch-i18n[data-i18nkey] 类名和属性的标签内容 */ function setLanguage () { $(SELECTOR+'['+ATTR+']').each(function () { var value = $(this).attr(ATTR); if(value && value != "") { if(this.tagName.toLowerCase() === 'input') { if( $(this).attr("placeholder")) { $(this).attr("placeholder",i18n[value]); } else if($(this).attr("value")){ $(this).attr("value",i18n[value]); } } else { $(this).html(i18n[value]); } } }); } window.CHI18n = CHI18nFactory ;})();
对于i18n.js的实现其实很简单,就是通过 jquery 加载所有 class="ch-i18n" 的元素,然后获取该元素的 data-i18nkey 属性值,然后通过浏览器地址栏参数 local 的值去加载对应的国际化文件,通过 data-i18nkey 的值去获取对应的文本显示即可。
当然有时候国际化文本中的数据可能是动态的,存在占位符的情况,比如:
{
msg:"我叫{{name}},今年{{age}}岁,性别{{sex}}"
}
这里的name,age,sex 占位符的值需要我们在设置的时候手动传值进去,因此可以给 get 方法传递一个参数即可,如下:
chI18n.get("msg" , {name:'king',age:24,sex:'男'})
如上只是一种简单的国际化方案,如果你有其他更好的方式,欢迎留言交流。