资讯专栏INFORMATION COLUMN

JS魔法堂:不完全国际化&本地化手册 之 实战篇

paraller / 2714人阅读

摘要:前言最近加入到新项目组负责前端技术预研和选型,其中涉及到一个熟悉又陌生的需求国际化本地化。注意苹果官网采用的是的机制提供本地化功能,和本篇主打前端实现有所区别。它们分别是处理排序的处理日期格式化的和处理数字货币等格式化的。

前言

 最近加入到新项目组负责前端技术预研和选型,其中涉及到一个熟悉又陌生的需求——国际化&本地化。熟悉的是之前的项目也玩过,陌生的是之前的实现仅仅停留在"有"的阶段而已。趁着这个机会好好学习整理一下,为后面的技术选型做准备。
 本篇将于大家一起挽起袖子撸代码:)

如何获取Language tag?

 在实现本地化处理前,我们起码先要获取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入参生成的最终采用的options
Intl.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入参生成的最终采用的options
Intl.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,maximumFractionDigitsminimumFractionDigits为一组,而maximumSignificantDigitsminimumSignificantDigits为另一组,当设置maximumSignificantDigits后,minimumIntegerDigits这组的设置为全部失效。

 上述Intl接口并不是所有浏览器均支持,幸好有大牛已为了我们准备好polyfill了,但由于Intl.Collator所以来的规则和实现的代码量较庞大,因此polyfill中仅仅实现了Intl.DateTimeFormat和Intl.NumberFormat接口而已,不过对于一般项目而言应该足矣。Intl polyfill
 另外,还对String,NumberDate的原型作扩展,以便我们使用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组件使用示例:



  
  

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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/80516.html

相关文章

  • JS魔法:完全际化&地化手册 拓展

    摘要:前言最近加入到新项目组负责前端技术预研和选型,其中涉及到一个熟悉又陌生的需求国际化本地化。因此不是表示存在多个选择而是表示没有适合的选项。 前言  最近加入到新项目组负责前端技术预研和选型,其中涉及到一个熟悉又陌生的需求——国际化&本地化。熟悉的是之前的项目也玩过,陌生的是之前的实现仅仅停留在有的阶段而已。趁着这个机会好好学习整理一下,为后面的技术选型做准备。 本篇作为系列的最后一篇,...

    Karuru 评论0 收藏0
  • JS魔法:完全际化&地化手册 理論

    摘要:前言最近加入到新项目组负责前端技术预研和选型,其中涉及到一个熟悉又陌生的需求国际化本地化。本篇将阐述国际化和本地化的概念,以及其中一个很重要的概念也叫或。语法注意一般采用首字母大写,后续字母全小写指定与国家地域对应的语言方言文化。 前言  最近加入到新项目组负责前端技术预研和选型,其中涉及到一个熟悉又陌生的需求——国际化&本地化。熟悉的是之前的项目也玩过,陌生的是之前的实现仅仅停留在有...

    yacheng 评论0 收藏0
  • JS魔法实战:纯前端的图片预览

    摘要:一前言图片上传是一个普通不过的功能,而图片预览就是就是上传功能中必不可少的子功能了。偶然从上找到纯前端图片预览的相关资料,经过整理后记录下来以便日后查阅。类型为,表示在读取文件时发生的错误,只读。 一、前言   图片上传是一个普通不过的功能,而图片预览就是就是上传功能中必不可少的子功能了。在这之前,我曾经通过订阅input[type=file]元素的onchange事件,一旦更改路径...

    岳光 评论0 收藏0
  • CSS魔法:重拾Border——图片作边框

    摘要:一铺搞定一铺清袋粤语的一铺搞定其实就是一次完成全部工作的意思,上面关于的属性,要是每次都逐个设置那要敲多少次键盘啊。。。语法粤语的一铺清袋其实就是把之前的成果一次性归零。 前言  当CSS3推出border-radius属性时我们是那么欣喜若狂啊,一想到终于不用再添加额外元素来模拟圆角了,但发现border-radius还分水平半径和垂直半径,然后又发现border-top-left/...

    linkFly 评论0 收藏0
  • 前端资源系列(4)-前端学习资源分享&前端面试资源汇总

    摘要:特意对前端学习资源做一个汇总,方便自己学习查阅参考,和好友们共同进步。 特意对前端学习资源做一个汇总,方便自己学习查阅参考,和好友们共同进步。 本以为自己收藏的站点多,可以很快搞定,没想到一入汇总深似海。还有很多不足&遗漏的地方,欢迎补充。有错误的地方,还请斧正... 托管: welcome to git,欢迎交流,感谢star 有好友反应和斧正,会及时更新,平时业务工作时也会不定期更...

    princekin 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<