这段时间我从后台统计中发现,小站有不少来自台湾、香港的 IP,也有数条繁体中文的留言评论。于是,我想着给 Kevin's Space 增设一个简单的繁简转换功能,其实本站所使用的Impeka 主题是支持 WPML 插件的,但奈何该多语言插件实在是太厚重了,作罢。
几经测试,最后选择使用台湾老哥编写的 AutoHan,这个插件自动根据浏览器默认接受的语言类型来切换到用户比较习惯的繁体汉字,或简体汉字。台湾、新加坡、马来西亚、日本、中国大陆、香港、澳门等地区的人有不同汉字阅读习惯,也可以手动切换。
AutoHan 的核心实际就是下文的前端脚本,试了一下完全可以把它直接加载咱网页底部,俭省掉仪表盘中若干代码,节约开销。具体效果可以看看在线屏幕检测里的效果。该页面中的按钮为:<a id="StranLink" href="javascript:AutoHan_StranBody()">繁体中文</a>
,你可以把它添加在你希望放置的地方。
1. 一段实现自动繁简转换的脚本
<?php
/*
/* 自动繁简转换脚本,提取自 AutoHan
/* https://www.shephe.com/website/simplified-traditional-conversion/
*/
// error_reporting(E_ALL);
// ini_set('display_errors', '1');
header('Content-Type: text/javascript;charset=utf-8');
header("Expires: ".gmdate("D, d M Y H:i:s", time()+9460800000)." GMT"); //缓存 Std_StranJF 时间为 10 年
header("Cache-Control: max-age=9460800000"); //缓存过期时间设置为 10 年
echo '//'.$_SERVER['HTTP_ACCEPT_LANGUAGE']; //显示浏览器可接受的语言,用于 debug
?>
//var Browser_isFt = 0
//浏览器是否默认接受繁体汉字,0-简体,1-繁体
var Browser_isFt =''
var language = window.navigator.userLanguage || window.navigator.language;
if (language.match(/zh-c/i) != null){Browser_isFt = 0;}
else if (language.match(/zh-h/i) != null){Browser_isFt = 1}
else if (language.match(/zh-t/i) != null){Browser_isFt = 1}
else if (language.match(/zh/i) != null){Browser_isFt = 1}
else if (language.match(/jp/i) != null){Browser_isFt = 1}
else if (language.match(/ja/i) != null){Browser_isFt = 1}
else if (language.match(/ko/i) != null){Browser_isFt = 1}
else {Browser_isFt = 0}
var StranIt_Delay = 100
var StranLink_Obj = document.getElementById("StranLink")
if (typeof(StranLink_Obj) != "undefined" && StranLink_Obj !== null){var tmptxt=StranLink_Obj.innerHTML.toString()}
function Autohan_StranText(txt,toFT,chgTxt)
{
if(txt==""||txt==null)return ""
toFT= toFT==null?Body_isFt:toFT
if(chgTxt)txt=txt.replace((toFT?"简":"繁"),(toFT?"繁":"简"))
if(toFT==1){return Traditionalized(txt)}
else {return Simplized(txt)}
}
function AutoHan_TransBody(fobj)
{
if(typeof(fobj)=="object"){var obj=fobj.childNodes}
else
{
var obj=document.body.childNodes
}
for(var i=0;i<obj.length;i++)
{
var OO=obj.item(i)
if("||BR|HR|TEXTAREA|".indexOf("|"+OO.tagName+"|")>0||OO==StranLink_Obj)continue;
if(OO.title!=""&&OO.title!=null)OO.title=Autohan_StranText(OO.title);
if(OO.alt!=""&&OO.alt!=null)OO.alt=Autohan_StranText(OO.alt);
if(OO.tagName=="INPUT"&&OO.value!=""&&OO.type!="text"&&OO.type!="hidden")OO.value=Autohan_StranText(OO.value);
if(OO.nodeType==3){OO.data=Autohan_StranText(OO.data)}
else AutoHan_TransBody(OO)
}
}
function Autohan_JTPYStr()
{
return '皑蔼碍爱翱袄奥坝罢摆败颁办绊帮绑镑谤剥饱宝报鲍辈贝钡狈备惫绷笔毕毙闭边编贬变辩辫鳖瘪濒滨宾摈饼拨钵铂驳卜补参蚕残惭惨灿苍舱仓沧厕侧册测层诧搀掺蝉馋谗缠铲产阐颤场尝长偿肠厂畅钞车彻尘陈衬撑称惩诚骋痴迟驰耻齿炽冲虫宠畴踌筹绸丑橱厨锄雏础储触处传疮闯创锤纯绰辞词赐聪葱囱从丛凑窜错达带贷担单郸掸胆惮诞弹当挡党荡档捣岛祷导盗灯邓敌涤递缔点垫电淀钓调迭谍叠钉顶锭订东动栋冻斗犊独读赌镀锻断缎兑队对吨顿钝夺鹅额讹恶饿儿尔饵贰发罚阀珐矾钒烦范贩饭访纺飞废费纷坟奋愤粪丰枫锋风疯冯缝讽凤肤辐抚辅赋复负讣妇缚该钙盖干赶秆赣冈刚钢纲岗皋镐搁鸽阁铬个给龚宫巩贡钩沟构购够蛊顾剐关观馆惯贯广规硅归龟闺轨诡柜贵刽辊滚锅国过骇韩汉阂鹤贺横轰鸿红后壶护沪户哗华画划话怀坏欢环还缓换唤痪焕涣黄谎挥辉毁贿秽会烩汇讳诲绘荤浑伙获货祸击机积饥讥鸡绩缉极辑级挤几蓟剂济计记际继纪夹荚颊贾钾价驾歼监坚笺间艰缄茧检碱硷拣捡简俭减荐槛鉴践贱见键舰剑饯渐溅涧浆蒋桨奖讲酱胶浇骄娇搅铰矫侥脚饺缴绞轿较秸阶节茎惊经颈静镜径痉竞净纠厩旧驹举据锯惧剧鹃绢杰洁结诫届紧锦仅谨进晋烬尽劲荆觉决诀绝钧军骏开凯颗壳课垦恳抠库裤夸块侩宽矿旷况亏岿窥馈溃扩阔蜡腊莱来赖蓝栏拦篮阑兰澜谰揽览懒缆烂滥捞劳涝乐镭垒类泪篱离里鲤礼丽厉励砾历沥隶俩联莲连镰怜涟帘敛脸链恋炼练粮凉两辆谅疗辽镣猎临邻鳞凛赁龄铃凌灵岭领馏刘龙聋咙笼垄拢陇楼娄搂篓芦卢颅庐炉掳卤虏鲁赂禄录陆驴吕铝侣屡缕虑滤绿峦挛孪滦乱抡轮伦仑沦纶论萝罗逻锣箩骡骆络妈玛码蚂马骂吗买麦卖迈脉瞒馒蛮满谩猫锚铆贸么霉没镁门闷们锰梦谜弥觅绵缅庙灭悯闽鸣铭谬谋亩钠纳难挠脑恼闹馁腻撵捻酿鸟聂啮镊镍柠狞宁拧泞钮纽脓浓农疟诺欧鸥殴呕沤盘庞国爱赔喷鹏骗飘频贫苹凭评泼颇扑铺朴谱脐齐骑岂启气弃讫牵扦钎铅迁签谦钱钳潜浅谴堑枪呛墙蔷强抢锹桥乔侨翘窍窃钦亲轻氢倾顷请庆琼穷趋区躯驱龋颧权劝却鹊让饶扰绕热韧认纫荣绒软锐闰润洒萨鳃赛伞丧骚扫涩杀纱筛晒闪陕赡缮伤赏烧绍赊摄慑设绅审婶肾渗声绳胜圣师狮湿诗尸时蚀实识驶势释饰视试寿兽枢输书赎属术树竖数帅双谁税顺说硕烁丝饲耸怂颂讼诵擞苏诉肃虽绥岁孙损笋缩琐锁獭挞抬摊贪瘫滩坛谭谈叹汤烫涛绦腾誊锑题体屉条贴铁厅听烃铜统头图涂团颓蜕脱鸵驮驼椭洼袜弯湾顽万网韦违围为潍维苇伟伪纬谓卫温闻纹稳问瓮挝蜗涡窝呜钨乌诬无芜吴坞雾务误锡牺袭习铣戏细虾辖峡侠狭厦锨鲜纤咸贤衔闲显险现献县馅羡宪线厢镶乡详响项萧销晓啸蝎协挟携胁谐写泻谢锌衅兴汹锈绣虚嘘须许绪续轩悬选癣绚学勋询寻驯训讯逊压鸦鸭哑亚讶阉烟盐严颜阎艳厌砚彦谚验鸯杨扬疡阳痒养样瑶摇尧遥窑谣药爷页业叶医铱颐遗仪彝蚁艺亿忆义诣议谊译异绎荫阴银饮樱婴鹰应缨莹萤营荧蝇颖哟拥佣痈踊咏涌优忧邮铀犹游诱舆鱼渔娱与屿语吁御狱誉预驭鸳渊辕园员圆缘远愿约跃钥岳粤悦阅云郧匀陨运蕴酝晕韵杂灾载攒暂赞赃脏凿枣灶责择则泽贼赠扎札轧铡闸诈斋债毡盏斩辗崭栈战绽张涨帐账胀赵蛰辙锗这贞针侦诊镇阵挣睁狰帧郑证织职执纸挚掷帜质钟终种肿众诌轴皱昼骤猪诸诛烛瞩嘱贮铸筑驻专砖转赚桩庄装妆壮状锥赘坠缀谆浊兹资渍踪综总纵邹诅组钻致钟么为只凶准启板里雳余链泄';
}
function FTPYStr()
{
return '皚藹礙愛翺襖奧壩罷擺敗頒辦絆幫綁鎊謗剝飽寶報鮑輩貝鋇狽備憊繃筆畢斃閉邊編貶變辯辮鼈癟瀕濱賓擯餅撥缽鉑駁蔔補參蠶殘慚慘燦蒼艙倉滄廁側冊測層詫攙摻蟬饞讒纏鏟産闡顫場嘗長償腸廠暢鈔車徹塵陳襯撐稱懲誠騁癡遲馳恥齒熾沖蟲寵疇躊籌綢醜櫥廚鋤雛礎儲觸處傳瘡闖創錘純綽辭詞賜聰蔥囪從叢湊竄錯達帶貸擔單鄲撣膽憚誕彈當擋黨蕩檔搗島禱導盜燈鄧敵滌遞締點墊電澱釣調叠諜疊釘頂錠訂東動棟凍鬥犢獨讀賭鍍鍛斷緞兌隊對噸頓鈍奪鵝額訛惡餓兒爾餌貳發罰閥琺礬釩煩範販飯訪紡飛廢費紛墳奮憤糞豐楓鋒風瘋馮縫諷鳳膚輻撫輔賦複負訃婦縛該鈣蓋幹趕稈贛岡剛鋼綱崗臯鎬擱鴿閣鉻個給龔宮鞏貢鈎溝構購夠蠱顧剮關觀館慣貫廣規矽歸龜閨軌詭櫃貴劊輥滾鍋國過駭韓漢閡鶴賀橫轟鴻紅後壺護滬戶嘩華畫劃話懷壞歡環還緩換喚瘓煥渙黃謊揮輝毀賄穢會燴彙諱誨繪葷渾夥獲貨禍擊機積饑譏雞績緝極輯級擠幾薊劑濟計記際繼紀夾莢頰賈鉀價駕殲監堅箋間艱緘繭檢堿鹼揀撿簡儉減薦檻鑒踐賤見鍵艦劍餞漸濺澗漿蔣槳獎講醬膠澆驕嬌攪鉸矯僥腳餃繳絞轎較稭階節莖驚經頸靜鏡徑痙競淨糾廄舊駒舉據鋸懼劇鵑絹傑潔結誡屆緊錦僅謹進晉燼盡勁荊覺決訣絕鈞軍駿開凱顆殼課墾懇摳庫褲誇塊儈寬礦曠況虧巋窺饋潰擴闊蠟臘萊來賴藍欄攔籃闌蘭瀾讕攬覽懶纜爛濫撈勞澇樂鐳壘類淚籬離裏鯉禮麗厲勵礫曆瀝隸倆聯蓮連鐮憐漣簾斂臉鏈戀煉練糧涼兩輛諒療遼鐐獵臨鄰鱗凜賃齡鈴淩靈嶺領餾劉龍聾嚨籠壟攏隴樓婁摟簍蘆盧顱廬爐擄鹵虜魯賂祿錄陸驢呂鋁侶屢縷慮濾綠巒攣孿灤亂掄輪倫侖淪綸論蘿羅邏鑼籮騾駱絡媽瑪碼螞馬罵嗎買麥賣邁脈瞞饅蠻滿謾貓錨鉚貿麽黴沒鎂門悶們錳夢謎彌覓綿緬廟滅憫閩鳴銘謬謀畝鈉納難撓腦惱鬧餒膩攆撚釀鳥聶齧鑷鎳檸獰甯擰濘鈕紐膿濃農瘧諾歐鷗毆嘔漚盤龐國愛賠噴鵬騙飄頻貧蘋憑評潑頗撲鋪樸譜臍齊騎豈啓氣棄訖牽扡釺鉛遷簽謙錢鉗潛淺譴塹槍嗆牆薔強搶鍬橋喬僑翹竅竊欽親輕氫傾頃請慶瓊窮趨區軀驅齲顴權勸卻鵲讓饒擾繞熱韌認紉榮絨軟銳閏潤灑薩鰓賽傘喪騷掃澀殺紗篩曬閃陝贍繕傷賞燒紹賒攝懾設紳審嬸腎滲聲繩勝聖師獅濕詩屍時蝕實識駛勢釋飾視試壽獸樞輸書贖屬術樹豎數帥雙誰稅順說碩爍絲飼聳慫頌訟誦擻蘇訴肅雖綏歲孫損筍縮瑣鎖獺撻擡攤貪癱灘壇譚談歎湯燙濤縧騰謄銻題體屜條貼鐵廳聽烴銅統頭圖塗團頹蛻脫鴕馱駝橢窪襪彎灣頑萬網韋違圍爲濰維葦偉僞緯謂衛溫聞紋穩問甕撾蝸渦窩嗚鎢烏誣無蕪吳塢霧務誤錫犧襲習銑戲細蝦轄峽俠狹廈鍁鮮纖鹹賢銜閑顯險現獻縣餡羨憲線廂鑲鄉詳響項蕭銷曉嘯蠍協挾攜脅諧寫瀉謝鋅釁興洶鏽繡虛噓須許緒續軒懸選癬絢學勳詢尋馴訓訊遜壓鴉鴨啞亞訝閹煙鹽嚴顔閻豔厭硯彥諺驗鴦楊揚瘍陽癢養樣瑤搖堯遙窯謠藥爺頁業葉醫銥頤遺儀彜蟻藝億憶義詣議誼譯異繹蔭陰銀飲櫻嬰鷹應纓瑩螢營熒蠅穎喲擁傭癰踴詠湧優憂郵鈾猶遊誘輿魚漁娛與嶼語籲禦獄譽預馭鴛淵轅園員圓緣遠願約躍鑰嶽粵悅閱雲鄖勻隕運蘊醞暈韻雜災載攢暫贊贓髒鑿棗竈責擇則澤賊贈紮劄軋鍘閘詐齋債氈盞斬輾嶄棧戰綻張漲帳賬脹趙蟄轍鍺這貞針偵診鎮陣掙睜猙幀鄭證織職執紙摯擲幟質鍾終種腫衆謅軸皺晝驟豬諸誅燭矚囑貯鑄築駐專磚轉賺樁莊裝妝壯狀錐贅墜綴諄濁茲資漬蹤綜總縱鄒詛組鑽緻鐘麼為隻兇準啟闆裡靂餘鍊洩';
}
function Traditionalized(cc){
var str='',ss=Autohan_JTPYStr(),tt=FTPYStr();
for(var i=0;i<cc.length;i++)
{
if(cc.charCodeAt(i)>10000&&ss.indexOf(cc.charAt(i))!=-1)str+=tt.charAt(ss.indexOf(cc.charAt(i)));
else str+=cc.charAt(i);
}
return str;
}
function Simplized(cc){
var str='',ss=Autohan_JTPYStr(),tt=FTPYStr();
for(var i=0;i<cc.length;i++)
{
if(cc.charCodeAt(i)>10000&&tt.indexOf(cc.charAt(i))!=-1)str+=ss.charAt(tt.indexOf(cc.charAt(i)));
else str+=cc.charAt(i);
}
return str;
}
function setCookie(name, value)
{
var argv = setCookie.arguments;
var argc = setCookie.arguments.length;
var expires = (argc > 2) ? argv[2] : null;
if(expires!=null)
{
var LargeExpDate = new Date ();
LargeExpDate.setTime(LargeExpDate.getTime() + (expires*1000*3600*24));
}
document.cookie = name + "=" + escape (value)+((expires == null) ? "" : ("; expires=" +LargeExpDate.toGMTString()));
}
function getCookie(Name)
{
var search = Name + "="
if(document.cookie.length > 0)
{
offset = document.cookie.indexOf(search)
if(offset != -1)
{
offset += search.length
end = document.cookie.indexOf(";", offset)
if(end == -1) end = document.cookie.length
return unescape(document.cookie.substring(offset, end))
}
else return ""
}
}
function AutoHan_StranBody(fobj)
{
if(Body_isFt==0)
{ StranLink_Obj.innerHTML=Autohan_StranText(tmptxt,0,1)
document.getElementById("StranLink").title=Autohan_StranText(document.getElementById("StranLink").title,null,1)
Body_isFt=1
setCookie(JF_cn,Body_isFt,14)
}
else
{ StranLink_Obj.innerHTML=Autohan_StranText(tmptxt,1,1)
document.getElementById("StranLink").title=Autohan_StranText(document.getElementById("StranLink").title,null,1)
Body_isFt=0
setCookie(JF_cn,Body_isFt,14)
}
AutoHan_TransBody()
}
var JF_cn="AutoHan+"+self.location.hostname.toString().replace(/\./g,"")
var Body_isFt=getCookie(JF_cn)
if(Body_isFt== null )
{
Body_isFt=Browser_isFt;
setCookie(JF_cn,Body_isFt,14);
}
if(typeof(StranLink_Obj) != "undefined" && StranLink_Obj !== null){
with(StranLink_Obj)
{
if(typeof(document.all)!="object")
{
href="javascript:AutoHan_StranBody()"
}
else
{
href="#";
onclick= new Function("AutoHan_StranBody();return false")
}
if(Body_isFt == 1)
{
title=Autohan_StranText("点击浏览繁体中文网页",0,1)
if (typeof(innerHTML) != "undefined" && innerHTML !== null){
innerHTML=Autohan_StranText(innerHTML,0,1)
}
}
else{
title=Autohan_StranText("点击浏览繁体中文网页",1,1)
if (typeof(innerHTML) != "undefined" && innerHTML !== null){
innerHTML=Autohan_StranText(innerHTML,1,1)
}
}
}
}
setTimeout("AutoHan_TransBody()",StranIt_Delay)
将这段代码保存为 PHP 文件加载到网页底部,即可实现语言的自动转换。如果需要用户手动切换,可以在页面中添加一个按钮(<a id="StranLink" href="javascript:AutoHan_StranBody()">繁体中文</a>
),绑定点击事件调用转换功能。
2. 繁简转换脚本的功能实现(via ChatGPT)
2.1 自动检测语言
代码通过浏览器的navigator.language
或navigator.userLanguage
属性获取用户的语言环境,并通过正则表达式判断是否为简体中文、繁体中文或其他语言:
var language = window.navigator.userLanguage || window.navigator.language;
if (language.match(/zh-c/i) != null) { Browser_isFt = 0; } // 简体
else { Browser_isFt = 1; } // 繁体或其他
2.2 简繁转换逻辑
转换功能基于两个字符映射表,分别存储简体和繁体的对应字符。通过遍历文本内容,将每个字符替换为目标字符集中的对应值:
function Traditionalized(cc) { ... } // 简体 -> 繁体
function Simplized(cc) { ... } // 繁体 -> 简体
2.3 持久化用户偏好
用户的语言偏好会通过setCookie
和getCookie
函数存储到浏览器的 cookie 中,下次访问时自动加载。示例:
setCookie("AutoHan+example.com", Body_isFt, 14);
2.4 页面内容转换
代码使用递归方法遍历 DOM 树,对文本节点、输入框内容以及 HTML 属性进行转换。核心函数为:
function AutoHan_TransBody(fobj) {
var obj = fobj ? fobj.childNodes : document.body.childNodes;
for (var i = 0; i < obj.length; i++) {
var OO = obj.item(i);
if (OO.nodeType == 3) { OO.data = Autohan_StranText(OO.data); }
else { AutoHan_TransBody(OO); }
}
}
2.5 用户手动切换语言
如果需要用户主动切换,可以在页面中添加一个元素(例如按钮),并设置点击事件触发语言切换逻辑:
function AutoHan_StranBody() {
Body_isFt = 1 - Body_isFt;
setCookie(JF_cn, Body_isFt, 14);
AutoHan_TransBody();
}
按钮可以这样实现:
<a id="StranLink" href="javascript:AutoHan_StranBody()">切换语言</a>
2.6 缓存与性能优化
脚本通过 HTTP 头部设置长时间缓存,减少加载次数,提升网页性能:
header("Expires: ".gmdate("D, d M Y H:i:s", time()+9460800000)." GMT");
header("Cache-Control: max-age=9460800000");
这代码看不懂,真的看不懂…………………🤣