Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >JS魔法堂:不完全国际化&本地化手册 之 实战篇

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

作者头像
^_^肥仔John
发布于 2018-01-18 09:33:06
发布于 2018-01-18 09:33:06
1.6K00
代码可运行
举报
运行总次数:0
代码可运行

前言

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

如何获取Language tag?

 在实现本地化处理前,我们起码先要获取Language tag吧?那么获取方式分为两类 1.直接获取浏览器的Language tag信息  一般来说浏览器语言的版本标示着用户所属或所期待接收哪种语言文化风俗的内容,于是通过以下函数获取浏览器的语言信息即可获取language-tag

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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

 用于字符排序.

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
new Intl.Collator([locales[, options]])
@param Array|String [locales] - language-tag字符串或数组
@param Array        [options] - 配置项

options的属性及属性值(如无特别说明则values第一个值为默认值)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@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' 

实例方法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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

 用于日期格式化输出.

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
new Intl.DateTimeFormat([locales[, options]])
@param Array|String [locales] - language-tag字符串或数组
@param Array        [options] - 配置项

options的属性及属性值(如无特别说明则values第一个值为默认值)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@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'

实例方法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Intl.Collator.prototype.format(a):String
@desc 格式化日期

Intl.DateTimeFormat.prototype.resolveOptions():Object
@desc 返回根据构造函数中options入参生成的最终采用的options

Intl.NumberFormat

 用于数字、货币格式化输出.

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
new Intl.NumberFormat([locales[, options]])
@param Array|String [locales] - language-tag字符串或数组
@param Array        [options] - 配置项

options的属性及属性值(如无特别说明则values第一个值为默认值)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@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的三剑客!

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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一下。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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使用示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<div id="msg"></div>
<script>
  const msgs = {en: {GREETING: 'Hello {name}'}
               ,fr: {GREETING: 'Bonjour {name}'}}  
  const locale = getLang()
  const msg = (msgs[locale] || msgs.en).GREETING
  const txt = new IntlMessageFormat(msg, locale)
  document.getElementById('msg').textContent = txt.format({name: 'fsjohnhuang'})
</script>

Polymer组件使用示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<link rel="import" href="./bower_components/app-localize-behavior/app-localize-behavior.html">
<dom-module id="x-demo">
  <template>
    <div>{{localize('name')}}</div>
  </template>
  <script>
    Polymer({
      is: 'x-demo',
      properties: {name: {type: String, value: 'fsjohnhuang'}},
      behaviors: [Polymer.AppLocalizeBehavior],
      attached: function(){
        this.loadResources(this.resolveUrl('./locales.json'))
      }
    })
  </script>
</dom-module>

locales.json

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{"en": {"GREETING": "Hello {name}"}
,"fr": {"GREETING": "Bonjour {name}"}}

更多的玩法请参考官网吧!

总结

 项目中我们更多地是采用如Formatjs等上层i18n库,而不是更底层的IntlAPI,但若想更好地实现国际化和本地化,我想了解Intl及其背后的规则是十分有必要的。  另外细心的你会发现上文提到另一个概念——Server-driven Negotiation,到底它和国际化/本地化有什么关系呢?那么请期待下篇——《JS魔法堂:不完全国际化&本地化手册 之 拓展篇》

感谢

Intl

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016-09-27 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
HarmonyOS NEXT实战:千分分隔符工具
##HarmonyOS Next实战##HarmonyOS SDK应用服务##教育##
中雨
2025/06/25
950
内置于浏览器中的国际化API[每日前端夜话0xBA]
你的程序很有可能需要支持多种语言。其中包括对语言敏感的日期处理。一个广受欢迎的库Moment.js【https://www.npmjs.com/package/moment】有助于实现这一目标,它的功能之一是国际化。其源代码【https://github.com/moment/moment/blob/develop/locale/en-gb.js】中包含对许多不同语言的本地化。现在这可能已经不是最好的方法了,因为我们有 ECMAScript 国际化 API。
疯狂的技术宅
2019/09/10
1.5K0
内置于浏览器中的国际化API[每日前端夜话0xBA]
什么,你还在用 momentJs 处理相对时间
我想,下面这段代码,你是不是在开发中常常这样使用来计算距离现在过去了多长时间: import moment from 'moment' // 61k (gzipped:19.k) function
前端修罗场
2023/10/07
2840
什么,你还在用 momentJs 处理相对时间
记一次平淡无奇的性能优化
甘特图的主要作用是项目管理,可以用图示的方式通过活动列表和时间刻度形象地表示出任何特定项目的活动顺序与持续时间,如下图
玖柒的小窝
2021/09/24
4950
记一次平淡无奇的性能优化
91.HarmonyOS NEXT 应用国际化与本地化指南:打造全球化应用
通过合理的国际化和本地化策略,可以使应用更好地适应全球市场。在实际开发中,要注意平衡功能完整性和性能表现,确保良好的用户体验。
全栈若城
2025/03/16
1410
JS魔法堂:不完全国际化&本地化手册 之 理論篇
前言  最近加入到新项目组负责前端技术预研和选型,其中涉及到一个熟悉又陌生的需求——国际化&本地化。熟悉的是之前的项目也玩过,陌生的是之前的实现仅仅停留在"有"的阶段而已。趁着这个机会好好学习整理一下,为后面的技术选型做准备。  本篇将阐述国际化和本地化的概念,以及其中一个很重要的概念——Language tag(也叫Language code 或 Culture)。 何为国际化?  国际化我认为就是应用支持多语言和文化习俗(数字、货币、日期和字符比较算法等),而本地化则是应用能识别用户所属文化习俗自动适
^_^肥仔John
2018/01/18
8400
105.精读《What's new in javascript》
2019 年 Google I/O 介绍了一些激动人心的 JS 新特性,这些特性有些已经被主流浏览器实现,并支持 polyfill,有些还在草案阶段。
黄子毅
2022/03/14
5560
JS魔法堂:不完全国际化&本地化手册 之 拓展篇
前言  最近加入到新项目组负责前端技术预研和选型,其中涉及到一个熟悉又陌生的需求——国际化&本地化。熟悉的是之前的项目也玩过,陌生的是之前的实现仅仅停留在"有"的阶段而已。趁着这个机会好好学习整理一下,为后面的技术选型做准备。  本篇作为系列的最后一篇,打算和大家一起看看HTTP的Content Negotiation机制和更多关于本地化的应用方向。 Content Negotiation(内容协同)  记得第一次接触国际化和本地化时是指服务端根据请求头字段Accept-Language获取languag
^_^肥仔John
2018/01/18
5430
JS魔法堂:不完全国际化&本地化手册 之 拓展篇
Javascript 字符串与文本格式化
JavaScript中的 String 类型用于表示文本型的数据. 它是由无符号整数值(16bit)作为元素而组成的集合. 字符串中的每个元素在字符串中占据一个位置. 第一个元素的index值是0, 下一个元素的index值是1, 以此类推. 字符串的长度就是字符串中所含的元素个数.你可以通过String字面值或者String对象两种方式创建一个字符串。
acc8226
2022/05/17
8890
Spring周边:国际化、Format
Locale 类代表一个特定的地理、语言和国家环境。Locale 向一些对国家和语言、地理等比较敏感的类提供国家地区语言信息,这些类有DateFormat、NumberFormat等等。
WEBJ2EE
2019/11/06
8010
Spring周边:国际化、Format
你不知道的JavaScript APIs
这个APi 可以让我们知道用户何时离开了页面。准确地说,只要页面的可见性状态发生变化,无论是用户最小化、最大化窗口还是切换标签,该API都会触发一个事件 visibilitychange 。
前端小智@大迁世界
2022/10/28
8800
Java国际化/本地化实战
开发一个支持多国语言的Web应用程序,要求系统能够根据客户端的系统的语言类型返回对应的界面:英文的操作系统返回英文界面,而中文的操作系统则返回中文界面——这便是典型的i18n国际化问题。
JavaEdge
2020/05/27
2.5K0
Java国际化/本地化实战
Golang国际化(i18n)和本地化(l10n)指南
Go is a statically compiled language that gained a lot of popularity lately due to the fact that is simple, performant and fits really well with developing cloud applications. It has a strong, yet poorly documented sub-package level base library that deals with a lot of aspects related to internationalization (i18n) and localization (l10n), such as character encodings, text transformations, and locale-specific text handling. Let's see what we can do to master this library and make our Go applications locale aware.
李海彬
2018/07/26
5.7K1
Golang国际化(i18n)和本地化(l10n)指南
What's New in JavaScript
编者按:转载自 ThinkJS 专栏,作者是怡红公子,奇舞团一哥,360资深前端工程师。单身,帅,有钱,头发多...
苏南
2020/12/16
5080
What's New in JavaScript
JavaScript ES2021最值得期待的新特性解析
每年,JavaScript 的更新都会添加新特性。今年发布的是 ES2020 或称 ES11,预计 ES2021 或称 ES12 将于 2021 年中发布。添加到 JavaScript 的新特性都会经历四个阶段。在本文中,我将讨论已经进入第四阶段且已添加到谷歌 Chrome V8 引擎中的新特性。
深度学习与Python
2020/11/06
8390
JavaScript ES2021最值得期待的新特性解析
【小家Spring】聊聊Spring中的格式化:Formatter、AnnotationFormatterFactory、DateFormatter以及@DateTimeFormat...
Converter只完成了数据类型的转换,却不负责输入输出数据的格式化工作,日期时间、货币等虽都以字符串形式存在,却有不同的格式。
YourBatman
2019/09/03
4.1K0
【小家Spring】聊聊Spring中的格式化:Formatter、AnnotationFormatterFactory、DateFormatter以及@DateTimeFormat...
身在外企,如何实现 React 应用国际化?
如果你在外企工作,那基本要天天做这件事情,比如我待过韩企和日企,我们的应用要支持韩文和英文,或者日文和英文。
神说要有光zxg
2024/05/31
3380
身在外企,如何实现 React 应用国际化?
一起来看看 Node.js v14.x LTS 中的这些新功能
作者简介:五月君,Software Designer,公众号「Nodejs技术栈」作者。 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时。在 2020 年 10 月 27 日 Node.js v14.15.0 LTS 版已发布,即长期支持版本,其中包含了很多很棒的新功能,以下内容也是基于笔者在日常 Node.js 工作和学习中所总结的,可能不全,同时也欢迎补充,有些功能之前也曾单独写过文章来介绍,接下让我们一起看看都有哪些新的变化?
五月君
2021/02/24
1K0
一起来看看 Node.js v14.x LTS 中的这些新功能
JavaScript 权威指南第七版(GPT 重译)(四)
JavaScript 对象在第六章中有所涉及。该章将每个对象视为一组独特的属性,与其他对象不同。然而,通常有必要定义一种共享某些属性的对象类。类的成员或实例具有自己的属性来保存或定义它们的状态,但它们还具有定义其行为的方法。这些方法由类定义,并由所有实例共享。例如,想象一个名为 Complex 的类,表示并对复数执行算术运算。Complex 实例将具有保存复数的实部和虚部(状态)的属性。Complex 类将定义执行这些数字的加法和乘法(行为)的方法。
ApacheCN_飞龙
2024/03/23
6560
JavaScript 权威指南第七版(GPT 重译)(四)
Flutter International 国际化,Localization 本地化, 使用Intl
项目地址: https://github.com/RustFisher/localization_demo
AnRFDev
2021/02/01
2.2K0
Flutter International 国际化,Localization 本地化, 使用Intl
推荐阅读
相关推荐
HarmonyOS NEXT实战:千分分隔符工具
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档