PHP*_*Pst 25 html javascript css localization cross-browser
如何在不更改字符代码的情况下设置阿拉伯数字的变体?
Eastern Arabic ? ? ? ? ? ? ? ? ? ?
Persian variant ? ? ? ? ? ? ? ? ? ?
Western Arabic 0 1 2 3 4 5 6 7 8 9
(And perhaps any other in use numeral system if any)
Run Code Online (Sandbox Code Playgroud)
这是一个示例代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<div lang="fa">0123456789</div>
<div lang="ar">0123456789</div>
<div lang="en">0123456789</div>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
我怎样才能做到这一点只使用客户端技术(HTML,CSS,JS)?
解决方案应该对页面的SEO分数没有负面影响.
请注意,在Windows文本框(例如"运行")中,根据周围文本的语言正确显示数字.
另请参阅:桌面应用程序中的数字本地化
Vis*_*ioN 13
这是一种代码转换的方法:
// Eastern Arabic (officially "Arabic-Indic digits")
"0123456789".replace(/\d/g, function(v) {
return String.fromCharCode(v.charCodeAt(0) + 0x0630);
}); // "??????????"
// Persian variant (officially "Eastern Arabic-Indic digits (Persian and Urdu)")
"0123456789".replace(/\d/g, function(v) {
return String.fromCharCode(v.charCodeAt(0) + 0x06C0);
}); // "??????????"
Run Code Online (Sandbox Code Playgroud)
演示: http ://jsfiddle.net/bKEbR/
这里我们使用Unicode移位,因为任何Unicode组中的数字都与拉丁组(即[0x0030 ... 0x0039])中的数字顺序相同.因此,例如,对于阿拉伯语 - 印度语组的转变是0x0630.
注意,我很难区分东方字符,所以如果我犯了一个错误(Unicode中有很多不同的东方字符组),你总是可以使用任何在线Unicode表来计算移位.您可以使用官方Unicode字符代码图表或Unicode Online Chartable.
人们必须决定这是一个外观问题还是一个转变问题。还必须确定这是一个涉及字符级语义或数字表示的问题。以下是我的想法:
如果我们遇到 Unicode 没有分离数字字符代码的情况,这个问题将具有完全不同的语义。然后,适当地显示不同的字形只是使用适当的字体的问题。另一方面,不可能像我在下面所做的那样简单地写出不同的字符而不改变字体。(情况并不完全完美,因为字体不一定涵盖 16 位 Unicode 集的整个范围,更不用说 32 位 Unicode 集了。)
9, ? (Arabic), ? (Urdu), 玖 (Chinese, complex), ? (Thai), ? (Tamil) etc.
Run Code Online (Sandbox Code Playgroud)
现在,假设我们接受 Unicode 语义,即 '9' 、'?' 和 '?' 是不同的字符,我们可能会得出结论,问题不在于外观(本来在 CSS 的范围内),而在于转换——稍后对此有一些想法,现在让我们假设情况就是这样。在关注字符级语义时,情况与字母和字母发生的情况并没有太大不同。例如,希腊语“?” 和拉丁语 'a' 被认为是不同的,即使拉丁字母与 Euboea 中使用的希腊字母几乎相同。也许更引人注目的是,相应的大写变体“?” (希腊语)和“A”(拉丁语)在几乎所有支持这两种文字的字体中在视觉上是相同的,
陈述了基本规则之后,让我们看看如何通过忽略它们来回答问题,特别是忽略(字符级)Unicode 语义。
(可怕、讨厌且不向后兼容) 解决方案: 使用将“0”到“9”映射到所需字形的字体。我不知道任何这样的字体。您将不得不使用 @font-face 和一些经过适当黑客攻击的字体来做您想做的事。
不用说,我并不是特别喜欢这个解决方案。但是,这是我所知道的唯一一个简单的解决方案,它可以在服务器端或客户端完成问题所要求的“不更改字符代码”。(从技术上讲,我在下面提出的 Cufon 解决方案也不会更改字符代码,但它所做的将文本绘制到画布中要复杂得多,并且还需要调整开源代码)。
注意: 任何转换解决方案,即更改 DOM 并将“0”到“9”范围内的字符替换为它们的阿拉伯语等价物的任何解决方案都将破坏期望数字以其原始形式出现在 DOM 中的代码。在讨论表单和输入时,这个问题当然是最糟糕的。
采用转换方法的答案的一个例子是:
$("[lang='fa']").find("*").andSelf().contents().each(function() {
if (this.nodeType === 3)
{
this.nodeValue = this.nodeValue.replace(/\d/g, function(v) {
return String.fromCharCode(v.charCodeAt(0) + 0x0630);
});
}
});
Run Code Online (Sandbox Code Playgroud)
注意:代码取自 VisioN 的第二个 jsFiddle。如果这是您唯一喜欢的答案部分,请确保您支持 VisioN 的答案,而不是我的!!!:-)
这有两个问题:
input(和textarea)元素内部发生的事情的问题。如果输入字段初始化为“42”,它将零售该值。这可以很容易地修复,但是存在实际输入的问题......人们可能决定在字符出现时改变它们,在它们改变时转换值等等。如果进行了这种转换,那么客户端和服务器端都需要准备好处理不同种类的数字。如果用非标准格式的数字输入 Javascript、jQuery 甚至 Globalize(客户端)和 ASP.NET、PHP 等(服务器端)中的开箱即用的东西...... 一个稍微更全面的解决方案(还要注意 input/textarea 元素,包括它们的初始值和用户输入)可能是:
//before the DOM change, test1 holds a numeral parseInt can understand
alert("Before: test holds the value:" +parseInt($("#test1").text()));
function convertNumChar(c) {
return String.fromCharCode(c.charCodeAt(0) + 0x0630);
}
function convertNumStr(s) {
return s.replace(/\d/g, convertNumChar);
}
//the change in the DOM
$("[lang='fa']").find("*").andSelf().contents()
.each(function() {
if (this.nodeType === 3)
this.nodeValue = convertNumStr(this.nodeValue);
})
.filter("input:text,textarea")
.each(function() {
this.value = convertNumStr(this.value)
})
.change(function () {this.value = convertNumStr(this.value)});
//test1 now holds a numeral parseInt cannot understand
alert("After: test holds the value:" +parseInt($("#test1").text()))
Run Code Online (Sandbox Code Playgroud)
整个 jsFiddle 可以在这里找到:http : //jsfiddle.net/bKEbR/13/
不用说,这只是部分解决了上述问题。客户端和/或服务器端代码必须识别非标准数字并将它们适当地转换为标准格式或实际值。
这不是几行javascript就能解决的简单问题。这只是这种可能转换的最简单情况,因为需要应用一个简单的字符到字符的映射来从一种形式的数字转换到另一种形式。
另一种基于外观的方法:
基于 Cufon 的解决方案(矫枉过正、非向后兼容(需要画布)等): 人们可以相对轻松地调整像 Cufon 这样的库来执行预期的操作。Cufon 可以做它的事情并在画布对象上绘制字形,除了调整将确保当元素具有特定属性时,将使用所需的字形而不是通常选择的字形。Cufon 和其他类似的库倾向于向 DOM 添加元素并改变现有元素的外观但不触及它们的文本,因此转换方法的问题不应该适用。事实上,有趣的是,虽然(调整后的)Cufon 就整体 DOM 而言提供了一种清晰的转换方法,但就其心态而言,它是一种基于外观的解决方案;我称之为混合解决方案。
替代混合解决方案: 使用阿拉伯语内容创建新的 DOM 元素,隐藏旧元素但保留其 ID 和内容不变。将阿拉伯语内容元素与其对应的隐藏元素同步。
让我们尝试跳出框框思考(框框是当前的 Web 标准)。
某些字符是独特的这一事实并不意味着它们不相关。而且,这并不一定意味着它们的区别在于外观。例如,“a”和“A”是同一个字母;在某些情况下,它们被认为是相同的,而在另一些情况下,它们被认为是不同的。有了,Unicode(以及之前的 ASCII 和 ISO-Latin-1 等)的区别意味着需要付出一些努力来克服它。CSS 提供了一种快速简便的方法来改变字母的大小写。例如,body {text-transform:uppercase}将页面正文中文本中的所有字母都转换为大写。请注意,这也是外观变化而不是转换的情况:body 元素的 DOM 没有变化,只是它的呈现方式发生了变化。
注意:如果 CSS 支持类似的东西numerals-transform: 'ar',那可能是这个问题的理想答案,因为它的措辞。
但是,在我们急于告诉 CSS 委员会添加此功能之前,我们可能需要考虑这意味着什么。在这里,我们正在解决一个小问题,但他们必须处理大局。
输出:这个数字转换功能是否允许“10”(2 个字符)显示为十(中文,简单)、拾(中文,复杂)、X(拉丁文)(所有 1 个字符)等等'ar',给出了适当的论据?
输入:这个数字转换特征是否会将“十”(中文,简单)更改为其对应的阿拉伯语,还是只是针对“10”?它会以某种方式巧妙地检测到“MMXI”(2012 年的拉丁数字)是一个数字而不是一个单词并相应地对其进行转换吗?
数字表示的问题并不像仅仅看这个问题想象的那么简单。
那么,这一切给我们留下了什么:
一个 CSS 解决方案会很好,但实际上,当我们查看涉及其他数字系统(与标准系统之间的转换较少)、小数点、符号等的大图时,问题是大而复杂的。
归根结底,我认为现实且向后兼容的解决方案是 Globalize(和服务器端等价物)的扩展,可能带有一些额外的代码来处理用户输入。这个想法是,这在字符级别不是问题(因为一旦您考虑大局,它就不是问题)并且必须以与处理千位和小数分隔符的差异相同的方式处理它:作为格式/解析问题。
一个新的(迄今为止)简单的 JS 解决方案是使用Intl.NumberFormat。它支持数字本地化、格式变化以及本地货币(有关更多示例,请参阅文档)。
使用与 MDN 非常相似的示例:
const val = 1234567809;
console.log('Eastern Arabic (Arabic-Egyptian)', new Intl.NumberFormat('ar-EG').format(val));
console.log('Persian variant (Farsi)',new Intl.NumberFormat('fa').format(val));
console.log('English (US)',new Intl.NumberFormat('en-US').format(val));Run Code Online (Sandbox Code Playgroud)
Intl.NumberFormat 似乎还支持字符串数值,并在它不是本地语言中的数字时进行指示。
const val1 = '456';
const val2 = 'Numeric + string example, 123';
console.log('Eastern Arabic', new Intl.NumberFormat('ar-EG').format(val1));
console.log('Eastern Arabic', new Intl.NumberFormat('ar-EG').format(val2));
console.log('Persian variant',new Intl.NumberFormat('fa').format(val1));
console.log('Persian variant',new Intl.NumberFormat('fa').format(val2));
console.log('English',new Intl.NumberFormat('en-US').format(val1));
console.log('English', new Intl.NumberFormat('en-US').format(val2));Run Code Online (Sandbox Code Playgroud)
对于区域设置标识符(传递给NumberFormat构造函数的字符串指示区域设置),我尝试了上面的值,它们看起来很好。我尝试查找所有可能值的列表,并通过 MDN 找到了此文档和此列表,它们可能会有所帮助。
我不熟悉搜索引擎优化,因此不确定这如何回答这部分问题。
| 归档时间: |
|
| 查看次数: |
2707 次 |
| 最近记录: |