前言
從10年接觸編程就開始接觸國(guó)際化這個(gè)概念,然而這些年全面用到國(guó)際化的項(xiàng)目并不是很多,且都是些螺絲釘式的工作。15年末,部門項(xiàng)目需要推國(guó)際化,前端這塊由我來(lái)主導(dǎo)。雖然難度不高,但還是拿出來(lái)分享下。
選擇方式:
目前了解到的前端國(guó)際化有以下兩種方式:
1、按語(yǔ)言種類分別開發(fā)前端界面:
這種方式貌似給人一種很low的感覺(jué)且覺(jué)著文件會(huì)無(wú)限多。然而在一般項(xiàng)目中語(yǔ)言種類并不會(huì)特別多,實(shí)現(xiàn)中英文兩種即可滿足大部分需求;并且這種方式如果配合上不同的網(wǎng)站風(fēng)格,不但可以解決中英文字符長(zhǎng)度差異問(wèn)題,而且可以兼顧不同群體的視覺(jué)感觀。但該方式后期維護(hù)中需要付出相當(dāng)于維護(hù)語(yǔ)言種類相同倍數(shù)的前端代碼;
2、使用配置文件:
使用一套界面,同樣的樣式文件,調(diào)用相對(duì)應(yīng)的語(yǔ)言文件進(jìn)行DOM渲染。該方式可以快速實(shí)現(xiàn),且只需維護(hù)一套前端文件。單頁(yè)應(yīng)用建議使用該方法。
如還有更好的方式,希望可以發(fā)出來(lái)學(xué)習(xí)下。
我的選擇:登陸,注冊(cè)等單獨(dú)存在于系統(tǒng)外圍的功能模塊使用第一種方式,其它主體功能選擇的是第二種方式。
第一種方式只需要按語(yǔ)言分類成多份文件,這里就直接跳過(guò)。單說(shuō)第二種方式,該如何實(shí)現(xiàn)。
實(shí)現(xiàn)步驟:
步驟一:準(zhǔn)備語(yǔ)言資源文件
原則上需要遵守一個(gè)界面對(duì)應(yīng)一個(gè)資源文件,再通過(guò)一個(gè)統(tǒng)一入口文件進(jìn)行資源整合。舉個(gè)栗子:
page1對(duì)應(yīng)的資源文件
var page1 = {
title:{
'zh-cn':'標(biāo)題',
'en-us':'title'
}
}
page2對(duì)應(yīng)的資源文件
var page2 = {
words:{
'zh-cn':'{0}共有{1}人使用',
'en-us':'{1} people use {0}'
}
}
整合文件
var i18nData = {
page1:page1,
page2:page2,
}
步驟二:引入主JS
自已實(shí)現(xiàn)了一個(gè)I18N對(duì)象,少碼字多貼代碼,直接上code~
var I18N = {
/*
* @存儲(chǔ)語(yǔ)言數(shù)據(jù)
* */
DATA : LD
/*
* @ 使用的語(yǔ)言
* */
,language: 'zh-cn'
/*
* @ 修改使用的語(yǔ)言
* */
,setLanguage: function(language){
this.language = language;
}
/*
* @解析string 語(yǔ)言標(biāo)記 用于解析html中的{{i18n-}}
* str:html string
* pageName:頁(yè)面名稱 、
* */
,parse: function(str, pageName){
var _this = this;
if(!pageName){
console.error('I18N解析失敗,原因pageName='+pageName);
return;
}
if(!_this.language){
console.error('I18N解析失敗,原因language='+_this.language);
return;
}
var key= '',
parseStr = '';
parseStr = str.replace(/{{i18n-(.+?)}}/g, function(t){
key = t.slice(7, t.length - 2);
try{
return _this.DATA[pageName][key][_this.language] || '';
}catch (e){
console.warn(pageName + '未找到與'+ key +'相匹配的'+ _this.language +'語(yǔ)言');
return '';
}
});
return parseStr;
}
/*
* 生成所需的文本信息 適用于js內(nèi)部更改DOM時(shí)使用
* pageName:頁(yè)面名稱
* key: 指向的文本索引
* v1,v2,v3:可為空,字符串格式,只存在v1時(shí)可為數(shù)組
* */
,getText: function(pageName, key, v1, v2, v3){
var _this = this;
var intrusion = [];
//處理參數(shù),實(shí)現(xiàn)多態(tài)化
if(arguments.length == 3 && typeof(arguments[2]) == 'object'){
intrusion = arguments[2];
}
else if(arguments.length > 2){
for(var i=2; i< arguments.length; i++){
intrusion.push(arguments[i]);
}
}
var _lg = '';
try{
_lg = _this.DATA[pageName][key][_this.language] || '';
if(!intrusion || intrusion.length == 0){
return _lg;
}
_lg = _lg.replace(/{d+}/g, function( word ){
return intrusion[word.match(/d+/)];
});
return _lg;
}catch (e){
console.warn('未找到與'+ key +'相匹配的'+ _this.language +'語(yǔ)言');
return '';
}
}
};
主程序加上注釋也僅僅70行,很簡(jiǎn)易。
步驟三:替換文本
配置使用的語(yǔ)言種類:
I18N.setLanguage('en-us'); //設(shè)置當(dāng)前使用的語(yǔ)言為美式英語(yǔ)
替換HTML文本:
首先需要將HTML中原文本更換為{{i18n-*}}格式的標(biāo)記,舉個(gè)栗子:
//格式上在借鑒angularjs雙向綁定的同時(shí)附加特定的標(biāo)識(shí)
<span>標(biāo)題</span> 替換為 <span>{{i18n-title}}</span>
然后在獲取到這段HTML的string格式文件后進(jìn)行匹配,舉個(gè)栗子:
//這里直接用jQuery的get方式進(jìn)行示例
//假設(shè)test.html可包含的文本為:<span>{{i18n-title}}</span>
//語(yǔ)言資源文件使用步驟一示例的數(shù)據(jù)
$.get(‘test.html’, function(htmlSrc){
var html = I18N.parse(htmlSrc, 'page1');
console.log(html); //將輸出<span>title</span>
$('body').html(html);
});
替換JS中的文本:
用于拼接字符串時(shí)處理含文本的字符,簡(jiǎn)單的舉個(gè)栗子:
//調(diào)用方法:getText(pageName, key, v1, v2, v3) 參數(shù)v1,v2,v3用于處理動(dòng)態(tài)數(shù)據(jù),可為空,字符串格式,只存在v1時(shí)可為數(shù)組
var _src = '<span>'
+ I18N.getText('page2', 'title', ['listManager.js', '10'])
+'</span>';
console.log(_src ); //將輸出 10 people use listManager.js
@拭目以待
表格管理插件:gridmanager.lovejavascript.com && github地址
QQ交流群 (452781895):How To Make Love