网页中英文语言切换解决方案
很多公司都喜欢把公司网站搞成双语言的,常见的办法是:做两份相同的程序,然后用不同的文件夹区分开来,然后点切换语言时,链接到不同的文件夹去就OK了,这种办法呢,如下:
好处是:各自的版本是分离开来的,比较稳定,不会出现互相干扰(共用数据库资料的除外!)等情况;
弊端是:改动一个功能,要把变更的操作(代码逻辑啊、图片PS啊、还有数据库等等)在所有的语言版本上面再重复一次,加重了操作量。
本来打算这样子搞的,但上头发话了,这样子代码管理比较麻烦,让哥哥想别的办法喔...那就想咯,别说,还真的想出了一个方法,虽然还未成熟,也不太稳定,但胜在不用修改原来的逻辑代码,而且只有一份代码够用了(是“够用”,不“是完美哦”!),我就不卖关子了,反正也不是什么秘密:说白了,其实就是用 js的replace()方法处理的,嘿嘿,只不过为了能让它能够快速布置,所以,需要做一些规范,怎么规范呢?还不太成熟哈,接着往下看就清楚了。
页面在客户端处显示给user看的都是<body>...</body>中的内容,既然如此,我直接把<body>...</body>中的内容中需要replace的中文全部replace掉再呈现出来就OK了吧,说干就干,直接先写一个“翻译字典”方法,如下:
dict.js
1 function setEnglish(bodyString) { 2 var result = bodyString; 3 result = result.replaceAll('發料量','Issue Qty'); 4 result = result.replaceAll('單位別','Unit'); 5 result = result.replaceAll('待交運','To be Delivered'); 6 result = result.replaceAll('應發量','Shoulsd Issue'); 7 result = result.replaceAll('應用量','Should Use'); 8 result = result.replaceAll('操作者','Operator'); 9 result = result.replaceAll('編輯中','Editing'); 10 result = result.replaceAll('確認者','Confirmed By'); 11 result = result.replaceAll('需求量','Required Qty'); 12 result = result.replaceAll('需求日','Required Day'); 13 result = result.replaceAll('實用量','Used Qty'); 14 result = result.replaceAll('跨工單','Inter-Shop Order'); 15 result = result.replaceAll('經辦人','Prepared by'); 16 result = result.replaceAll('損耗率','Yield Loss Rate'); 17 result = result.replaceAll('超耗量','Over Consumption '); 18 result = result.replaceAll('超比例','Over-proportional'); 19 result = result.replaceAll('結案日','Close Date'); 20 result = result.replaceAll('發料量','Issue Qty'); 21 result = result.replaceAll('換工單','Change Shop Order'); 22 result = result.replaceAll('提報數','Report Qty'); 23 result = result.replaceAll('報廢量','Scrap Form'); 24 result = result.replaceAll('報廢單','Scrap Form'); 25 result = result.replaceAll('報廢品','Scrap Unit'); 26 result = result.replaceAll('單位別','Unit'); 27 result = result.replaceAll('移轉數','Transfer Qty'); 28 result = result.replaceAll('移入量','Move In Qty'); 29 result = result.replaceAll('異動碼','Transaction Code'); 30 result = result.replaceAll('接受量','Received Qty'); 31 result = result.replaceAll('庫存量','Inventory'); 32 result = result.replaceAll('凈移轉','Net Transfers'); 33 result = result.replaceAll('待發量','To be Issued'); 34 result = result.replaceAll('待報廢','To be Scrapped'); 35 result = result.replaceAll('待處理','To be Processed'); 36 result = result.replaceAll('待重工','To be Reworked'); 37 result = result.replaceAll('待交運','To Be Delivered'); 38 result = result.replaceAll('待分配','To be Assigned'); 39 result = result.replaceAll('物流中','Logistics'); 40 result = result.replaceAll('來料量','Incoming Qty'); 41 result = result.replaceAll('良品數','Good Unit Qty'); 42 result = result.replaceAll('材料批','Component Part Lot Batch'); 43 result = result.replaceAll('投入數','Input Qty'); 44 result = result.replaceAll('完成日','Completion Date'); 45 result = result.replaceAll('在製量','WIP'); 46 result = result.replaceAll('在移量','Transit Qty'); 47 result = result.replaceAll('全 部','All'); 48 result = result.replaceAll('分派數','Distribute Qty'); 49 result = result.replaceAll('不良數','Reject Qty'); 50 result = result.replaceAll('已檢驗','Inspected'); 51 result = result.replaceAll('已移轉','Transferred'); 52 result = result.replaceAll('已交運','Shipped'); 53 result = result.replaceAll('工單號','Shop Order No.'); 54 result = result.replaceAll('下工站','Next Operation'); 55 result = result.replaceAll('上工站','Previous Operation'); 56 result = result.replaceAll('入檢序','Incoming Inspection Operation '); 57 result = result.replaceAll('入料量','Incoming Qty'); 58 result = result.replaceAll('創建者','Founder'); 59 result = result.replaceAll('請選擇','Please Choose'); 60 result = result.replaceAll('編輯中','Editing'); 61 result = result.replaceAll('物流中','In Logistics'); 62 result = result.replaceAll('待處理','To be Processed'); 63 result = result.replaceAll('待重工','To be Reworked'); 64 result = result.replaceAll('待報廢','To be Scrapped'); 65 result = result.replaceAll('待分配','To be Assigned'); 66 result = result.replaceAll('待交運','To be Delivered'); 67 result = result.replaceAll('已檢驗','Inspected'); 68 result = result.replaceAll('已移轉','Transferred'); 69 result = result.replaceAll('全 部','All'); 70 result = result.replaceAll('移轉單','Transfer Form'); 71 result = result.replaceAll('報廢單','Scrap Form'); 72 result = result.replaceAll('待交運','To be Delivered'); 73 result = result.replaceAll('淨移轉','Net Transfers'); 74 result = result.replaceAll('經辦人','Operator'); 75 result = result.replaceAll('确定者','Affirmant'); 76 result = result.replaceAll('日期起','Start Date'); 77 result = result.replaceAll('測試區','Test'); 78 result = result.replaceAll('導出','Export'); 79 result = result.replaceAll('料號','Part No.'); 80 result = result.replaceAll('工單','Shop Order'); 81 result = result.replaceAll('鏈接','Hyperlink'); 82 result = result.replaceAll('儲位','Location'); 83 result = result.replaceAll('選擇','Option'); 84 result = result.replaceAll('機種','Model'); 85 result = result.replaceAll('導出','Export'); 86 result = result.replaceAll('確定','OK'); 87 result = result.replaceAll('標記','Symbol'); 88 result = result.replaceAll('標工','Standard'); 89 result = result.replaceAll('廠商','Supplier'); 90 result = result.replaceAll('新建','New'); 91 result = result.replaceAll('搜索','Search'); 92 result = result.replaceAll('用戶','User ID'); 93 result = result.replaceAll('密碼','Password'); 94 result = result.replaceAll('語言','Language'); 95 result = result.replaceAll('確認','Confirm'); 96 result = result.replaceAll('損耗','Yield Loss'); 97 result = result.replaceAll('移出','Move Out'); 98 result = result.replaceAll('料號','Part No.'); 99 result = result.replaceAll('料件','Material Part'); 100 result = result.replaceAll('倉庫','Store'); 101 result = result.replaceAll('重工','Rework'); 102 result = result.replaceAll('客戶','Customer Name'); 103 result = result.replaceAll('品保','QA'); 104 result = result.replaceAll('時間','Date'); 105 result = result.replaceAll('返回','Back'); 106 result = result.replaceAll('注解','Remarks'); 107 result = result.replaceAll('類型','Type'); 108 result = result.replaceAll('周數','Weeks'); 109 result = result.replaceAll('其他','Others'); 110 result = result.replaceAll('良品','Good Unit'); 111 result = result.replaceAll('材料','Component Part'); 112 result = result.replaceAll('批號','Lot Batch No.'); 113 result = result.replaceAll('批量','Lot Size'); 114 result = result.replaceAll('作成','Made'); 115 result = result.replaceAll('余量','Margin'); 116 result = result.replaceAll('用量','Used Qty'); 117 result = result.replaceAll('方式','Approach'); 118 result = result.replaceAll('工單','Shop Order'); 119 result = result.replaceAll('工序','Operation No.'); 120 result = result.replaceAll('工序','Operation '); 121 result = result.replaceAll('人工','Manpower'); 122 result = result.replaceAll('狀態','Status'); 123 result = result.replaceAll('其他','Others'); 124 result = result.replaceAll('工單','Shop Order'); 125 result = result.replaceAll('新建','New'); 126 result = result.replaceAll('導出','Export'); 127 result = result.replaceAll('其他','Others'); 128 result = result.replaceAll('搜尋','Search'); 129 result = result.replaceAll('料號','Part No.'); 130 result = result.replaceAll('全部','All'); 131 result = result.replaceAll('返回','Back'); 132 result = result.replaceAll('廠區','Factory'); 133 result = result.replaceAll('查詢','Search'); 134 result = result.replaceAll('确定','Confirm'); 135 result = result.replaceAll('部門',' Department'); 136 result = result.replaceAll('操作','Operation'); 137 result = result.replaceAll('移入','Move In'); 138 result = result.replaceAll('單位','Unit'); 139 result = result.replaceAll('說明','Description'); 140 result = result.replaceAll('數量','Qty'); 141 result = result.replaceAll('保存','Save'); 142 result = result.replaceAll('儲','Store'); 143 result = result.replaceAll('倉','Store'); 144 result = result.replaceAll('批','Batch'); 145 result = result.replaceAll('迄','Until'); 146 result = result.replaceAll('入','In'); 147 result = result.replaceAll('出','Out'); 148 149 return result; 150 }
PS:这个方法就是把传进来的东西进行翻译后,再把翻译的结果return回去的,注意:js里面没有replaceAll这个方法的,上面的是我自己加上去的,后面会给出;还有,根据翻译的字段长短,先把replace长的,再replace短的,长的一般用replace()就够了,短的最好用replaceAll(),当然有特殊情况的,这里不多说,反正遇到了就明白怎么整了;另外,怎么这么长的?呵呵,这部分可以找别人提供,还有,上面这些“result = result.replaceAll(.....)”是我直接在Excel导出来的(当然,中英对照表是让别的同事搞的,不必亲自出马),网上会的人应该比较多,排序麻,需要一点点技巧,但不难,所以不用怕,当然,我QQ空间日志有一篇日志里有提到,没加到俺QQ的,可以让你妹妹或姐姐啊加我也行,我这个人比较随和的,哈。
有了这个方法还不够,还要考虑一下用户体验的东西,比如:要用cookie记住user目前的语言种类,以便下次直接默认。
有了想法,那需要什么,就去做了,比如cookie的处理类,replaceAll()方法的定义,还有切换语言的逻辑等等,下面都有了,我先贴上网上搜集的一个cookie处理方法,源码如下:
cookiesHelper.js
1 //寫cookies函數 2 //作者:翟振凯 3 function SetCookie(name,value)//兩個參數,一個是cookie的名字,一個是值 4 { 5 var Days = 30; //此 cookie 將被保存30天 6 var exp = new Date(); //new Date("December 31, 9998"); 7 exp.setTime(exp.getTime() + Days*24*60*60*1000); 8 document.cookie = name + "="+ escape (value) + ";expires=" + exp.toGMTString(); 9 } 10 function getCookie(name)//取cookies函數 11 { 12 var arr = document.cookie.match(new RegExp("(^| )"+name+"=([^;]*)(;|$)")); 13 if(arr != null) return unescape(arr[2]); return null; 14 15 } 16 function delCookie(name)//刪除cookie 17 { 18 var exp = new Date(); 19 exp.setTime(exp.getTime() - 1); 20 var cval=getCookie(name); 21 if(cval!=null) document.cookie= name + "="+cval+";expires="+exp.toGMTString(); 22 } 23 24 25 //示例 26 //SetCookie ("xiaoqi", "3") 27 //alert(getCookie('xiaoqi')); 28 29 30 //URL字符串操作 31 function request(name) { 32 var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); 33 var r = window.location.search.substr(1).match(reg); 34 if (r != null) return unescape(r[2]); return null; 35 } 36 37 //為系統追加replaceAll方法 38 String.prototype.replaceAll = function(oldStr, newStr) { 39 return this.replace(new RegExp(oldStr,"gm"),newStr); 40 } 41
PS:自己看一下方法,觉得不错的话,可以果断收走了,最后一个方法就是为字符串对象追加一个replaceAll()方法,有了这个,才能执行上面的替换所有字符的对象(这个有虾米用?要是有个GridView控件呢,下面一大堆重复的内容,单纯的replace()只能替换第一个匹配到的字符串,后面的就无能为力了,除非你多替换几次咯),这个方法也出来以后啊,就剩最后一步的啦~
在需要进行翻译的页面<head>...</head>加入如下代码:
1 <script src="js/jquery-1.6.js" type="text/javascript"></script> 2 <script src="js/cookiesHelper.js" type="text/javascript"></script> 3 <script src="js/dict.js" type="text/javascript"></script> 4 <script type="text/javascript"> 5 //add by seasons.zhang 2012/09/20 6 $(function () { 7 //根據cookie切換語言種類 8 if (getCookie("somoveLanguage") == "en") { 9 var result = setEnglish($("body").html()); 10 $("body").html(result); 11 } 12 }); 13 </script>
PS:Jquery是神马?这个必须引用的,我写的是基于jquery的(没有jquery的日子很难过啊,哈哈~)。原网页是中文的,当cookie("somoveLanguage")的值为"en"时,才调用replace方法,否则不鸟它。
神奇吧?翻译就这样搞定了!但是呢,使用过程中总会有一些毛病的,我大概说点吧,比如DropDownList控件,假如像下面的个的话
1 <select name="seasons1987"> 2 <option value="哥只是个传说">哥只是个传说</option> 3 <option value="哥不止是个传说">哥不止是个传说</option> 4 <option value="哥一直都是个传说">哥一直都是个传说</option> 5 <option value="不要迷恋哥">不要迷恋哥</option> 6 </select>
看到上面了吗?如果调用replaceAll("哥只是个传说","Seasons1987")的话,第一项的value跟text都会发生改变了,这样子在asp.net中有一个叫做ViewStatus的东东就会找你麻烦了,一个折中的办法是把replace语句改为replaceAll(">哥只是个传说<",">Seasons1987<")就可以避免这个问题啦。又比如,一些写在<body>...</body>里面的<script ...> ...</script>的js方法,经过jquery的html()方法重新写入之后,会破坏它的功用的,也就是翻译之后,就失效了,我遇到的一个问题是:某个用js动态的修改<td>的width跟height的方法失效了,应该是涉及到“用js修改css属性”的功能就会有毛病,我也不太明白,目前的研究只止步于此,毕竟还要忙着解决单身问题啊,呵呵。当然,解决办法还是有的,举个例如下:
1 <body> 2 <p>哥只是个传说啊</p> 3 <input name="Seasons1987" value="2012-10-04" onclick="XXXX" /> 4 <p>哥还是个传说啊</p> 5 <p>征婚啊...</p>
6 </body>
假定,上面的input有一个onclick的事件,当我把<body>全部传进行翻译时,onclick会失效的话,可以这样子改一下<body>的代码,大概如下:
1 <body> 2 <span id="body1"><p>哥只是个传说啊</p></span> 3 <input name="Seasons1987" value="2012-10-04" onclick="XXXX" /> 4 <span id="body2">
4 <p>哥还是个传说啊</p> 5 <p>征婚啊...</p>
6 </span>
7 </body>
然后,<head>中的代码可以这样子写:
1 <script src="js/jquery-1.6.js" type="text/javascript"></script> 2 <script src="js/cookiesHelper.js" type="text/javascript"></script> 3 <script src="js/dict.js" type="text/javascript"></script> 4 <script type="text/javascript"> 5 //add by seasons.zhang 2012/09/20 6 $(function () { 7 //根據cookie切換語言種類 8 if (getCookie("somoveLanguage") == "en") { 9 var body1= setEnglish($("#body1").html()); 10 var body2= setEnglish($("#body2").html()); 11 $("#body1").html(body1); 12 $("#body2").html(body2); 13 } 14 }); 15 </script>
最最后,怎么切换语言呢?随便咯,我提供一个,大家按照自己的想法来做就行了,比如弄个下接框选择语言啊,或者搞两幅小国旗,点哪切哪都行,两种都用过,这里贴下拉框的,如下:
1 <head> 2 <script src="js/jquery-1.6.js" type="text/javascript"></script> 3 <script src="js/cookiesHelper.js" type="text/javascript"></script> 4 <script src="js/dict.js" type="text/javascript"></script> 5 <script type="text/javascript"> 6 //add by seasons.zhang 2012/09/20 7 function chgLang() { 8 SetCookie("somoveLanguage", $("#ddlSomoveLanguage").children('option:selected').val()); 9 //alert(getCookie("somoveLanguage")); 10 window.location = 'Default.aspx'; 11 } 12 </script> 13 </head> 14 <body> 15 <select id="ddlSomoveLanguage" onchange="return chgLang();"> 16 <option value="ch">中文</option> 17 <option value="en">英文</option> 18 </select> 19 </body>
OK,收队了!