1. 程式人生 > >前端多語言的實現

前端多語言的實現

前言

多語言的重要性相信不需要多言,但是,對於使用ExtJS之類的前端框架做開發,很多時候要使用一些多語言訊息,難道都寫在動態頁面裡?這樣,就會對動態頁面有依賴。如果說頁面是訪問量非常大的,比如:首頁,那麼靜態化是非常有必要的。那問題就來了,怎麼做多語言的靜態化?事實上,使用一些模板語言,是能做到多語言的靜態化,即根據不同語言,生成不同的靜態頁面。但是,這樣一來,靜態頁面就非常多了,而且很多地方是完全可複用的。理想的狀態是,我只要多語言的部分有不同版本,其他頁面組成,我只要一個就夠。於是乎,就有了我們這個解決方案。

一、前端多語言

前端多語言,是指依賴Javascript技術實現多語言的方案。本方案基於Javascript技術,對於語言配置的載入,依賴Ajax技術。本文中的實現,又是基於jQuery框架的。

二、原理介紹

實現前端多語言,實際上並不是實時的的多語言,而是文件載入完成後,對文件內容進行再處理的過程。核心思想是通過i18n屬性設定多語言的key,然後外掛對所有帶i18n屬性的dom進行掃描處理。但是前端多語言並不僅僅是這一個需求,進而延伸的還有事件函式中需要使用的訊息,比如新增一條資料後的提示訊息“新增成功”。這時,就需要對普通字串物件,即String物件進行處理,使其支援多語言。當然,以上的工作,基礎就是需要拿到多語言配置。而多語言訊息配置的獲取,則是通過ajax方式從伺服器獲取,當然,只抓取當前瀏覽器語言的。雖然其中涉及到一次額外的請求,但是,實際上使用.json檔案命名的多語言配置,是可以利用瀏覽器快取的。第一次載入之後,後續再次載入時,服務端是會告知瀏覽器訊息未變化,可複用快取的,即304。

三、實現

1、瀏覽器語言的獲取

/**
 * 獲取瀏覽器語言
 * @returns language
 */
function getLang(){
	if(typeof(cacheLang) != "undefined"){
		return cacheLang;
	}
	if (navigator.language) {
		cacheLang = navigator.language.toLowerCase();
		return cacheLang;
	}else {
		cacheLang = navigator.browserLanguage.toLowerCase();
		return cacheLang;
	}
}

2、多語言配置的載入

var url = $.type(p) == "string" ? p : "i18n/" + getLang() + ".json";//p為引數,可通過p手動指定配置路徑,此時不根據預設路徑載入多語言訊息配置
$.ajax({
	url : url,
	dataType : 'json',
	type : "GET",
	success : function(data, textStatus, jqXHR) {
		messages = data;//快取訊息
		run(data);//執行dom處理
		callback(self);//回撥處理,self為外掛本身物件
	},
	error : function(a, b, c) {
		throw "Load i18n message error [" + p + "], cause by : " + b;
	}
});

3、DOM處理

/**
 * 替換國際化訊息
 * @param ms 訊息物件
 */
function run(ms){
	$("*[i18n]").each(function(){
		var o = $(this);
		var key = o.attr("i18n");//獲取key
		var val = o.attr("i18n-set");//獲取訊息設定目標
		var message = _getMessage(ms, key);//取得訊息
		switch(val){//根據不同目標設定到不同的地方
		case undefined:
			o.html(message);
			break;
		case "append":
			o.html(o.html() + message);
			break;
		case "html":
			o.html(message);
			break;
		case "value":
			o.val(message);
			break;
		default:
			o.attr(val, message);
			break;
		}
		o.removeAttr("i18n");//移除屬性,避免二次處理
		o.removeAttr("i18n-set");
	});
}

4、獲取多語言的方法

/**
 * 獲取多語言訊息
 * @param msgs 訊息物件
 * @param key 訊息名稱
 * @returns value 訊息
 */
function _getMessage(msgs, key){
	var message;
	try{
		message = msgs[key];
	}catch(e){
		message = key;
	}
	return message;
}

5、實現對String物件的改造

/**
 * 為String提供local方法獲取多語言訊息
 * @return value 訊息
 */
String.prototype.local = function(){
	return _getMessage(messages, this);
}

四、使用

準備配置如下(i18n/zh-cn):
{
	"system.name" : "前端多語言實現",
	"system.copyright" : "Microsnow、tomtrije 版權所有",
	"install.title" : "安裝配置"
}

1、引入

<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/i18n.js"></script>

2、定義

<span class="title" i18n="system.name"></span>

3、初始化

/**
 * 頁面載入完成後,進行國際化訊息處理
 */
$(document).ready(function() {
	new com.wuningsi.i18n(init);//init為回撥函式,在國際化訊息初始化完成後繼續頁面其他初始化操作
});
初始化後,頁面中的國際化訊息實際上已經處理好了。但是,對於事件中即Javascript中使用的國際化訊息,是不一樣的。

4、Javascript中使用國際化訊息

alert("install.installing".local());

五、擴充套件點說明

1、本方案已實現擴充套件

除了第四節中說明的預設使用方式外,還有一些細的擴充套件點,細心的讀者肯定已經發現了,不過還是說明一下。 第一、可以手動指定目標多語言配置路徑。 第二、在init函式中接收到了外掛物件,可以對多語言訊息reload處理。 第三、利用好i18n-set屬性,可以實現不同語言的不同表單提交方式(這個自己琢磨去)。

2、本方案未實現擴充套件

第一、固定的i18n和i18n-set屬性名稱,完全可以做成配置式,由頁面決定。 第二、String的local函式,是對String物件有破壞的,比較講究的同學可以另闢他徑。 第三、哈,等待你挖掘…… THE END