前端國際化的另類方式

關於國際化

一個項目發展到必定的環境或者一開始就是爲多國打造的,就須要考慮國際化了。簡單來講,就是一套頁面,多套語言。css

前不久作了一個國際化的項目,基於reactantd,裏面用到了國際化,使用方式也很簡單html

import zhCN from 'antd/lib/locale-provider/zh_CN';

return (
  <LocaleProvider locale={zhCN}>
    <App />
  </LocaleProvider>
);

而後,頁面全部的官方組件都變成了中文(默認是英文)。前端

若是你使用其餘工程,也有相應的解決方案,好比vue

  • vue + vue-i18n
  • angular + angular-translate
  • react + react-intl
  • jquery + jquery.i18n.property

具體使用方式能夠自行搜索,無非就是看各類api和配置文件。react

能夠說至關成熟了,那麼,如何本身實現?jquery

國際化的實現原理

其實原理很簡單,這裏只講最基本的原理,不談框架的特性。web

上面列舉這裏這麼多js框架,有一個共同的特徵,就是都有一個相似語言包的東西。json

zh.json
en.json
jp.json
...

這個也很好理解,把各類語言獨立開來,便於管理和維護。segmentfault

便於測試,咱們把請求的過程去掉了,直接寫在一個json對象裏面,以下api

intl.js

var intl = 
{
    "zh": {
        "title": "測試",
        "content": "這是一個測試"
    },
    "cn": {
        "title": "test",
        "content": "this is a test"
    }
}

大概會寫一些這樣的配置語言,而後經過某種手段把對應的字段設置到相應的位置就能夠了。

下面是僞代碼

<h2 id="title">測試</h2>
<p id="content">這是一個測試</p>
var lang = getGlobalVar('LOCALE')||'zh';//獲取語言
var local = intl['lang'];

$title.innerHTML = local['title'];
$content.innerHTML = local['content'];

上面是一個簡單的實現思路,若是是一個簡單的靜態頁面,大能夠用這種方式,也不須要引入一些第三方庫,而後啃他的api

固然,國際化還遠不止頁面靜態文字的簡單翻譯,還包括本地化服務(時間、貨幣等等),若是涉及到這些仍是使用現成的庫來的快。

另類的嘗試

除了以上js的思路,還有沒有其餘的方法呢?這不是廢話嗎,若是沒有就不會來寫這篇文章了。

下面重點來了,如何不借助js來實現國際化?

國際化的解決要點

實現國際化有兩個基本要素

  • 語言配置
  • 前端呈現

語言配置是指如何設置多語言,也就是說如何把多種語言記錄下來,就像前面js裏面的配置文件。

前端配置是指如何根據須要把須要展現的語言顯示在頁面,好比在中文環境下顯示中文,英文環境下顯示英文,用戶看獲得纔算數。

乍一看,好像不借助js根本行不通啊,又要配置文件,又要渲染頁面內容,簡直無解啊。

content生成技術

css中有個content生成屬性,通常配合僞類:before或者:after來使用。

可能一提到content,不少人可能就明白了,沒錯,content就能夠實現內容生成。

那麼,試一試?

<!DOCTYPE html>
<html lang="en">
<body>
  <h2 class="title"></h2>
  <h3 class="paragraph"></h3>
  <h4 class="summary"></h4>
</body>
</html>
/**ch**/
html:lang(ch) .title:after{
  content: '標題';
}
html:lang(ch) .paragraph:after{
  content: '段落';
}
html:lang(ch) .summary:after{
  content: '描述';
}
/**en**/
html:lang(en) .title:after{
  content: 'title';
}
html:lang(en) .paragraph:after{
  content: 'paragraph';
}
html:lang(en) .summary:after{
  content: 'summary';
}

怎麼樣?是眼前一亮仍是。。很銼?

好吧,我也以爲很挫,寫起來比較麻煩,不過也是一種思路。

content+attr

上面的方式確實不怎麼樣,可是思惟也須要一個漸進的過程

下面用到了使用屬性值做爲content內容,以前的用純css實現打星星效果(三)也使用這個特性,你們有興趣能夠回過去看下,這裏簡單介紹一下用法

<style>
  span:after{content:attr(a)}
</style>
<span a="我是A"></span>

這樣就能夠經過屬性值來生成內容。

爲何要用屬性值呢?

上一種方式以前很差緣由還有一點,就是語義化太差,單獨看html文件徹底不知道是什麼內容

<h2 class="title"></h2>
<h3 class="paragraph"></h3>
<h4 class="summary"></h4>

下面我加點屬性

<h2 data-lang-ch="標題" data-lang-en="title"></h2>
<h3 data-lang-ch="段落" data-lang-en="paragraph"></h3>
<h4 data-lang-ch="描述" data-lang-en="summary"></h4>

這下語義化應該沒什麼問題了吧,很清楚知道每一個標籤的內容

你們應該知道我要作什麼了吧,以下

/**ch**/
html:lang(ch) [data-lang-ch]:after{
  content: attr(data-lang-ch);
}
/**en**/
html:lang(en) [data-lang-en]:after{
    content: attr(data-lang-en);
}

很簡單,各自取各自對應的屬性便可,須要什麼語言直接在html添加屬性便可,也不須要什麼js

結合以前講過的css地址選擇器,能夠很輕鬆的實現根據地址欄來適配各類語言

[data-lang-ch]:after,
#ch:target~[data-lang-ch]:after{
    content: attr(data-lang-ch);
}
#en:target~[data-lang-en]:after{
    content: attr(data-lang-en);
}

頁面添加一點元素

<body>
    <div id="ch"></div>
    <div id="en"></div>
    <h2 data-lang-ch="標題" data-lang-en="title"></h2>
    <h3 data-lang-ch="段落" data-lang-en="paragraph"></h3>
    <h4 data-lang-ch="描述" data-lang-en="summary"></h4>

    <a href="#ch">中文</a>
    <a href="#en">英文</a>
</body>

下面是demo

int

小節

以上主要探討了兩種徹底不一樣的國際化方式,前一種主流,後一種徹底屬於另類,但仍是有用武之地的。若是你的頁面不太複雜,徹底能夠採起這種方式。

沒有了js,速度也快了,視野也開闊了,腰也不酸了,腿也不疼了...

雖然以上跳過js實現了國際化需求,可是若是說是一些動態內容,好比時間,就無法放在屬性裏面的,這一部分,就只能經過js來處理了,實屬無奈。。

還有一個就是,若是頁面複雜,或者需適配語言太多,那就意味着屬性要寫不少

<h2 
  data-lang-ch="標題" 
  data-lang-en="title"
  data-lang-fr="XXX"
  data-lang-jp="XXX"
  data-lang-de="XXX"
  data-lang-fi="XXX"
  data-lang-it="XXX"
  >
</h2>

這樣就不太友好了,這種狀況下就推薦主流的js解決方式


若是喜歡的文章的話,能夠點贊並收藏,多多關注個人博客

相關文章
相關標籤/搜索