摘要:前言最近加入到新項目組負責前端技術預研和選型,其中涉及到一個熟悉又陌生的需求國際化本地化。注意蘋果官網采用的是的機制提供本地化功能,和本篇主打前端實現有所區別。它們分別是處理排序的處理日期格式化的和處理數字貨幣等格式化的。
前言
?最近加入到新項目組負責前端技術預研和選型,其中涉及到一個熟悉又陌生的需求——國際化&本地化。熟悉的是之前的項目也玩過,陌生的是之前的實現僅僅停留在"有"的階段而已。趁著這個機會好好學習整理一下,為后面的技術選型做準備。
?本篇將于大家一起挽起袖子擼代碼:)
?在實現本地化處理前,我們起碼先要獲取Language tag吧?那么獲取方式分為兩類
1.直接獲取瀏覽器的Language tag信息
?一般來說瀏覽器語言的版本標示著用戶所屬或所期待接收哪種語言文化風俗的內容,于是通過以下函數獲取瀏覽器的語言信息即可獲取language-tag
function getLang(){ return navigator.language || navigator.browserLanguage }
2.用戶選擇Language tag信息
?大家在瀏覽蘋果官網時也會發現以下界面,讓我們自行選擇language-tag。
注意蘋果官網采用的是Server-driven Negotiation的機制提供本地化功能,和本篇主打前端實現有所區別。
?最適當的設置和獲取language-tag的方式當然就是上述兩種方式相結合啦!首先自動獲取瀏覽器的Language tag信息,并提供入口讓用戶自行選擇Language tag信息。
認識JavaScript Internationalization API?有了本地化識別的根據(language tag)后,我們就可以開始實現本地化處理了,但從頭開始處理還累了,幸好H5為我們提供新的API來減輕我們的工作量。它們分別是處理排序的Intl.Collator,處理日期格式化的Intl.DateTimeFormat和處理數字/貨幣等格式化的Intl.NumberFormat。
Intl.Collator?用于字符排序.
new Intl.Collator([locales[, options]]) @param Array|String [locales] - language-tag字符串或數組 @param Array [options] - 配置項
options的屬性及屬性值(如無特別說明則values第一個值為默認值)
@prop String localeMatcher @desc 指定用于locale匹配的算法 @values "best fit" | "lookup" @prop String usage @desc 指定用途 @values "sort" | "search" @prop String sensitivity @desc 指定對比時是否忽略大小寫、讀音符號 @values "base" - 大小寫不敏感,讀音符號不敏感 "accent" - 除采用base規則外,讀音符號敏感 "case" - 除采用base規則外,大小寫敏感 "variant" - base,accent和case的并集 @prop Boolean ignorePunctuation @desc 指定是否忽略標點符號 @values false | true @prop Boolean numeric @desc 指定是否將兩個數字字符轉換為數字類型再作比較 @values false | true @prop String caseFirst @desc 指定是否以大寫或小寫作優先排序 @values "false" | "upper" | "lower"
實例方法
Intl.Collator.prototype.compare(a, b):Number @desc 比較字符串a和字符串b,若a排在b前面則返回-1,等于則返回0,排在后面則返回1. Intl.Collator.prototype.resolveOptions():Object @desc 返回根據構造函數中options入參生成的最終采用的optionsIntl.DateTimeFormat
?用于日期格式化輸出.
new Intl.DateTimeFormat([locales[, options]]) @param Array|String [locales] - language-tag字符串或數組 @param Array [options] - 配置項
options的屬性及屬性值(如無特別說明則values第一個值為默認值)
@prop String localeMatcher @desc 指定用于locale匹配的算法 @values "best fit" | "lookup" @prop String timeZone @desc 指定被格式化的時間所在的時區 @values [IANA time zone database](https://www.iana.org/time-zones) such as "Asia/Shanghai", "Asia/Kolkata", "America /New_York", "UTC" @prop String timeZoneName @desc 指定格式化后所顯示的時區樣式 @values "short" | "long" @prop Boolean hour12 @desc 指定采用12小時制還是24小時制 @values false | true @default-value 由locales入參決定 @prop String year @desc 指定年份的樣式 @values "numeric" | "2-digit" | "narrow" | "short" | "long" @prop String month @desc 指定月份的樣式 @values "numeric" | "2-digit" | "narrow" | "short" | "long" @prop String day @desc 指定日期的樣式 @values "numeric" | "2-digit" @prop String hour @desc 指定小時的樣式 @values undefined | "numeric" | "2-digit" @prop String minute @desc 指定分鐘的樣式 @values undefined | "numeric" | "2-digit" @prop String second @desc 指定秒的樣式 @values undefined | "numeric" | "2-digit" @prop String weekday @desc 指定周的樣式 @values "narrow" | "short" | "long"
實例方法
Intl.Collator.prototype.format(a):String @desc 格式化日期 Intl.DateTimeFormat.prototype.resolveOptions():Object @desc 返回根據構造函數中options入參生成的最終采用的optionsIntl.NumberFormat
?用于數字、貨幣格式化輸出.
new Intl.NumberFormat([locales[, options]]) @param Array|String [locales] - language-tag字符串或數組 @param Array [options] - 配置項
options的屬性及屬性值(如無特別說明則values第一個值為默認值)
@prop String localeMatcher @desc 指定用于locale匹配的算法 @values "best fit" | "lookup" @prop String style @desc 指定格式化的風格 @values "decimal" | "currency" | "percent" @remark 當style設置為currency后,屬性currency必須設置 @prop String currency @desc 指定貨幣的格式化信息 @values 如"USD"表示美元, "EUR"表示歐元, "CNY"表示RMB.[Current currency & funds code first](http://www.currency-iso.org/en/home/tables/table-a1.html) @prop String currencyDisplay @desc 指定貨幣符號的樣式 @values "symbol" | "code" | "name" @prop Boolean useGrouping @desc 指定是否采用如千位分隔符對數字進行分組 @values false | true @prop Number minimumIntegerDigits @desc 指定整數最小位數 @values 1-21 @prop Number maximumFractionDigits @desc 指定小數部分最大位數 @values 0-20 @prop Number minimumFractionDigits @desc 指定小數部分最小位數 @values 0-20 @prop Number maximumSignificantDigits @desc 指定有效位最大位數 @values 1-21 @prop Number minimumSignificantDigits @desc 指定有效為最小位數 @values 1-21
注意:minimumIntegerDigits,maximumFractionDigits和minimumFractionDigits為一組,而maximumSignificantDigits和minimumSignificantDigits為另一組,當設置maximumSignificantDigits后,minimumIntegerDigits這組的設置為全部失效。
?上述Intl接口并不是所有瀏覽器均支持,幸好有大牛已為了我們準備好polyfill了,但由于Intl.Collator所以來的規則和實現的代碼量較龐大,因此polyfill中僅僅實現了Intl.DateTimeFormat和Intl.NumberFormat接口而已,不過對于一般項目而言應該足矣。Intl polyfill
?另外,還對String,Number和Date的原型作擴展,以便我們使用Intl的三劍客!
String.prototype.localeCompare(compareString[, locales[, options]]) Number.prototype.toLocaleString([locales[, options]]) Date.prototype.toLocaleString([locales[, options]]) Date.prototype.toLocaleDateString([locales[, options]]) Date.prototype.toLocaleTimeString(([locales[, options]])Format.js——用在生產環境的i18n庫
?說了這么多那我們怎么讓項目實現國際化/本地化呢?那當然要找個可靠的第三方庫啦——Format.js,它不僅提供字符串替換還提供日期、數字和貨幣格式化輸出的功能,而且各大前端框架都已將其作二次封裝,使用得心應手呢!
要注意的是它依賴Intl.NumberFormat和Intl.DateTimeFormat,因此當瀏覽器部支持時需要polyfill一下。
var areIntlLocalesSupported = require("intl-locales-supported"); var localesMyAppSupports = [ /* list locales here */ ]; if (global.Intl) { // Determine if the built-in `Intl` has the locale data we need. if (!areIntlLocalesSupported(localesMyAppSupports)) { // `Intl` exists, but it doesn"t have the data we need, so load the // polyfill and replace the constructors with need with the polyfill"s. var IntlPolyfill = require("intl"); Intl.NumberFormat = IntlPolyfill.NumberFormat; Intl.DateTimeFormat = IntlPolyfill.DateTimeFormat; } } else { // No `Intl`, so use and load the polyfill. global.Intl = require("intl"); }
intl-locales-supported顧名思義就是檢查原生Intl是否支持特定的Language tag(如cmn-Hans),若不支持則使用Polyfill版本。
原生JavaScript使用示例:
Polymer組件使用示例:
{{localize("name")}}
locales.json
{"en": {"GREETING": "Hello {name}"} ,"fr": {"GREETING": "Bonjour {name}"}}
更多的玩法請參考官網吧!
總結?項目中我們更多地是采用如Formatjs等上層i18n庫,而不是更底層的IntlAPI,但若想更好地實現國際化和本地化,我想了解Intl及其背后的規則是十分有必要的。
?另外細心的你會發現上文提到另一個概念——Server-driven Negotiation,到底它和國際化/本地化有什么關系呢?那么請期待下篇——《JS魔法堂:不完全國際化&本地化手冊 之 拓展篇》
?尊重原創,轉載請注明來自: http://www.cnblogs.com/fsjohn... ^_^肥仔John
Intl
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/80516.html
摘要:前言最近加入到新項目組負責前端技術預研和選型,其中涉及到一個熟悉又陌生的需求國際化本地化。因此不是表示存在多個選擇而是表示沒有適合的選項。 前言 ?最近加入到新項目組負責前端技術預研和選型,其中涉及到一個熟悉又陌生的需求——國際化&本地化。熟悉的是之前的項目也玩過,陌生的是之前的實現僅僅停留在有的階段而已。趁著這個機會好好學習整理一下,為后面的技術選型做準備。?本篇作為系列的最后一篇,...
摘要:前言最近加入到新項目組負責前端技術預研和選型,其中涉及到一個熟悉又陌生的需求國際化本地化。本篇將闡述國際化和本地化的概念,以及其中一個很重要的概念也叫或。語法注意一般采用首字母大寫,后續字母全小寫指定與國家地域對應的語言方言文化。 前言 ?最近加入到新項目組負責前端技術預研和選型,其中涉及到一個熟悉又陌生的需求——國際化&本地化。熟悉的是之前的項目也玩過,陌生的是之前的實現僅僅停留在有...
摘要:一前言圖片上傳是一個普通不過的功能,而圖片預覽就是就是上傳功能中必不可少的子功能了。偶然從上找到純前端圖片預覽的相關資料,經過整理后記錄下來以便日后查閱。類型為,表示在讀取文件時發生的錯誤,只讀。 一、前言 圖片上傳是一個普通不過的功能,而圖片預覽就是就是上傳功能中必不可少的子功能了。在這之前,我曾經通過訂閱input[type=file]元素的onchange事件,一旦更改路徑...
摘要:一鋪搞定一鋪清袋粵語的一鋪搞定其實就是一次完成全部工作的意思,上面關于的屬性,要是每次都逐個設置那要敲多少次鍵盤啊。。。語法粵語的一鋪清袋其實就是把之前的成果一次性歸零。 前言 ?當CSS3推出border-radius屬性時我們是那么欣喜若狂啊,一想到終于不用再添加額外元素來模擬圓角了,但發現border-radius還分水平半徑和垂直半徑,然后又發現border-top-left/...
摘要:特意對前端學習資源做一個匯總,方便自己學習查閱參考,和好友們共同進步。 特意對前端學習資源做一個匯總,方便自己學習查閱參考,和好友們共同進步。 本以為自己收藏的站點多,可以很快搞定,沒想到一入匯總深似海。還有很多不足&遺漏的地方,歡迎補充。有錯誤的地方,還請斧正... 托管: welcome to git,歡迎交流,感謝star 有好友反應和斧正,會及時更新,平時業務工作時也會不定期更...
閱讀 3300·2021-11-23 09:51
閱讀 2911·2021-10-28 09:33
閱讀 875·2021-10-08 10:04
閱讀 3682·2021-09-22 15:13
閱讀 1015·2019-08-30 15:55
閱讀 2906·2019-08-30 15:44
閱讀 564·2019-08-30 13:04
閱讀 2938·2019-08-30 12:56