前端多语言的实现

前言

多语言的重要性相信不需要多言,但是,对于使用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、引入


2、定义

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







你可能感兴趣的:(前端)