我写了一个网络应用程序,其中包含多种语言的翻译(其中一种是希腊语。)
当在标题上显示某个翻译时,设计规则是文本应该是大写的,这在世界上任何其他语言中都很好,但是当涉及到希腊语时,浏览器不知道该怎么做使用重音(请参阅this),以便显示错误的大写字符串。
从我上面链接的那个补丁,我已经将它转换为Javascript,针对它运行了一些用例,并且它有效。现在我所要做的就是:
不向每个需要大写的元素添加uppercase
类(有很多),我可以使用计算样式属性查询DOM
吗? IE浏览器。给我所有具有计算text-transform: uppercase
答案 0 :(得分:12)
上述示例3 here
中描述了此问题的解决方案This is an example应该适用于任何浏览器(仅在Firefox 25上测试)
HTML:
<body>
<p id="withlang" lang="el">κεφαλαία με μετατροπή σύμφωνα με την γλώσσα</p>
<p id="withoutlang">κεφαλαία με μετατροπή σύμφωνα με αντιστοιχίσεις unicode</p>
<p id="withlangsmall" lang="el">μικρά κεφαλαία με μετατροπή σύμφωνα με την γλώσσα</p>
<p id="withoutlangsmall">μικρά κεφαλαία με μετατροπή σύμφωνα με αντιστοιχίσεις unicode</p>
</body>
CSS:
#withlang, #withoutlang{
text-transform: uppercase;
}
#withlangsmall, #withoutlangsmall{
font-variant: small-caps;
}
您还可以在更高级别使用lang属性,例如在body标记处。
HTML:
<body lang="el">
<p id="withlang">κεφαλαία με μετατροπή σύμφωνα με την γλώσσα</p>
<p id="withlangsmall">μικρά κεφαλαία με μετατροπή σύμφωνα με την γλώσσα</p>
</body>
CSS:
#withlang{
text-transform: uppercase;
}
#withlangsmall{
font-variant: small-caps;
}
答案 1 :(得分:11)
我强烈建议不要使用jQuery。而是这样做:
var e = document.getElementsByTagName('*'), l = e.length, i;
if( typeof getComputedStyle == "undefined")
getComputedStyle = function(e) {return e.currentStyle;};
for( i=0; i<l; i++) {
if( getComputedStyle(e[i]).textTransform == "uppercase") {
// do stuff with e[i] here.
}
}
使用10,000个元素进行测试,其中2,500个元素具有“大写”文本转换。
jQuery在595ms处理
JS在60ms处理
因此,JavaScript比jQuery快大约10倍。
编辑:另一项测试,这次有100,000个元素:
jQuery failed.TypeError:Object不支持属性或方法'each' JS在577ms处理
答案 2 :(得分:4)
我正在使用这个PHP函数:
function toUpper($str){
$search = array('Ά', 'Έ', 'Ί', 'Ή', 'Ύ', 'Ό', 'Ώ');
$replace = array('Α', 'Ε', 'Ι', 'Η', 'Υ', 'Ο', 'Ω');
$str = mb_strtoupper($str, "UTF-8");
return str_replace($search, $replace, $str);
}
答案 3 :(得分:3)
好的,仅供参考,到目前为止这是我的解决方案:
GREEK_CHARS = {
LOWER_ALPHA : 0x03B1
LOWER_ALPHA_ACC : 0x03AC
LOWER_EPSILON : 0x03B5
LOWER_EPSILON_ACC : 0x03AD
LOWER_ETA : 0x03B7
LOWER_ETA_ACC : 0x03AE
LOWER_IOTA : 0x03B9
LOWER_IOTA_ACC : 0x03AF
LOWER_IOTA_ACC_DIAERESIS : 0x0390
LOWER_OMICRON : 0x03BF
LOWER_OMICRON_ACC : 0x03CC
LOWER_UPSILON : 0x03C5
LOWER_UPSILON_ACC : 0x03CD
LOWER_UPSILON_ACC_DIAERESIS: 0x03B0
LOWER_OMEGA_ACC : 0x03CE
UPPER_ALPHA : 0x0391
UPPER_EPSILON : 0x0395
UPPER_ETA : 0x0397
UPPER_IOTA : 0x0399
UPPER_IOTA_DIAERESIS : 0x03AA
UPPER_OMICRON : 0x039F
UPPER_UPSILON : 0x03A5
UPPER_UPSILON_DIAERESIS : 0x03AB
UPPER_OMEGA : 0x03A9
UPPER_ALPHA_ACC : 0x0386
UPPER_EPSILON_ACC : 0x0388
UPPER_ETA_ACC : 0x0389
UPPER_IOTA_ACC : 0x038A
UPPER_OMICRON_ACC : 0x038C
UPPER_UPSILON_ACC : 0x038E
UPPER_OMEGA_ACC : 0x038F
COMBINING_ACUTE_ACCENT : 0x0301
COMBINING_DIAERESIS : 0x0308
COMBINING_ACUTE_TONE_MARK : 0x0341
COMBINING_GREEK_DIALYTIKA_TONOS : 0x0344
}
String::toUpperCaseWithoutGreek = String::toUpperCase
String::toUpperCase = ->
newStringCharCodes = []
insideTag = false
for char, idx in this
insideTag = true if char == '<'
insideTag = false if char == '>'
charCode = char.charCodeAt(0)
if insideTag
newStringCharCodes.push charCode
continue
prev = if idx > 0 then newStringCharCodes[idx-1] else GREEK_CHARS.UPPER_ALPHA
prevPrev = if idx > 1 then newStringCharCodes[idx-2] else GREEK_CHARS.UPPER_ALPHA
prevPrevPrev = if idx > 2 then newStringCharCodes[idx-3] else GREEK_CHARS.UPPER_ALPHA
switch charCode
when GREEK_CHARS.LOWER_ALPHA_ACC, GREEK_CHARS.UPPER_ALPHA_ACC
newStringCharCodes.push GREEK_CHARS.UPPER_ALPHA
when GREEK_CHARS.LOWER_EPSILON_ACC, GREEK_CHARS.UPPER_EPSILON_ACC
newStringCharCodes.push GREEK_CHARS.UPPER_EPSILON
when GREEK_CHARS.LOWER_ETA_ACC, GREEK_CHARS.UPPER_ETA_ACC
newStringCharCodes.push GREEK_CHARS.UPPER_ETA
when GREEK_CHARS.LOWER_IOTA_ACC, GREEK_CHARS.UPPER_IOTA_ACC
newStringCharCodes.push GREEK_CHARS.UPPER_IOTA
when GREEK_CHARS.LOWER_IOTA_ACC_DIAERESIS
newStringCharCodes.push GREEK_CHARS.UPPER_IOTA_DIAERESIS
when GREEK_CHARS.LOWER_OMICRON_ACC, GREEK_CHARS.UPPER_OMICRON_ACC
newStringCharCodes.push GREEK_CHARS.UPPER_OMICRON
when GREEK_CHARS.LOWER_UPSILON_ACC, GREEK_CHARS.UPPER_UPSILON_ACC
newStringCharCodes.push GREEK_CHARS.UPPER_UPSILON
when GREEK_CHARS.LOWER_UPSILON_ACC_DIAERESIS
newStringCharCodes.push GREEK_CHARS.UPPER_UPSILON_DIAERESIS
when GREEK_CHARS.LOWER_OMEGA_ACC, GREEK_CHARS.UPPER_OMEGA_ACC
newStringCharCodes.push GREEK_CHARS.UPPER_OMEGA
when GREEK_CHARS.LOWER_IOTA
switch prev
when GREEK_CHARS.LOWER_ALPHA_ACC, GREEK_CHARS.LOWER_EPSILON_ACC, GREEK_CHARS.LOWER_OMICRON_ACC
newStringCharCodes.push GREEK_CHARS.UPPER_IOTA_DIAERESIS
when GREEK_CHARS.LOWER_UPSILON_ACC
if prevPrev == GREEK_CHARS.LOWER_OMICRON
newStringCharCodes.push GREEK_CHARS.UPPER_IOTA
else
newStringCharCodes.push GREEK_CHARS.UPPER_IOTA_DIAERESIS
when GREEK_CHARS.COMBINING_ACUTE_ACCENT, GREEK_CHARS.COMBINING_ACUTE_TONE_MARK
switch prevPrev
when GREEK_CHARS.LOWER_ALPHA, GREEK_CHARS.LOWER_EPSILON, GREEK_CHARS.LOWER_OMICRON
newStringCharCodes.push GREEK_CHARS.UPPER_IOTA_DIAERESIS
when GREEK_CHARS.LOWER_UPSILON
if prevPrevPrev == GREEK_CHARS.LOWER_OMICRON
newStringCharCodes.push GREEK_CHARS.UPPER_IOTA
else
newStringCharCodes.push GREEK_CHARS.UPPER_IOTA_DIAERESIS
else
newStringCharCodes.push GREEK_CHARS.UPPER_IOTA
else
newStringCharCodes.push GREEK_CHARS.UPPER_IOTA
when GREEK_CHARS.LOWER_UPSILON
switch prev
when GREEK_CHARS.LOWER_ALPHA_ACC, GREEK_CHARS.LOWER_EPSILON_ACC, GREEK_CHARS.LOWER_ETA_ACC, GREEK_CHARS.LOWER_OMICRON_ACC
newStringCharCodes.push GREEK_CHARS.UPPER_UPSILON_DIAERESIS
when GREEK_CHARS.COMBINING_ACUTE_ACCENT, GREEK_CHARS.COMBINING_ACUTE_TONE_MARK
switch prevPrev
when GREEK_CHARS.LOWER_ALPHA, GREEK_CHARS.LOWER_EPSILON, GREEK_CHARS.LOWER_ETA, GREEK_CHARS.LOWER_OMICRON
newStringCharCodes.push GREEK_CHARS.UPPER_UPSILON_DIAERESIS
else
newStringCharCodes.push GREEK_CHARS.UPPER_UPSILON
else
newStringCharCodes.push GREEK_CHARS.UPPER_UPSILON
when GREEK_CHARS.COMBINING_GREEK_DIALYTIKA_TONOS
newStringCharCodes.push GREEK_CHARS.COMBINING_DIAERESIS
when GREEK_CHARS.COMBINING_ACUTE_ACCENT, GREEK_CHARS.COMBINING_ACUTE_TONE_MARK
if prev < GREEK_CHARS.LOWER_OMEGA_ACC && prev > GREEK_CHARS.UPPER_ALPHA_ACC
newStringCharCodes.push null
else
newStringCharCodes.push(String.fromCharCode(charCode).toUpperCaseWithoutGreek().charCodeAt(0))
String.fromCharCode.apply(null, newStringCharCodes)
这是一个改编自上述bug中提供的补丁的咖啡脚本。
以下是渲染视图后的操作:
# Fix greek uppercase.
[].concat($('*').get()).filter((elm) ->
window.getComputedStyle(elm).getPropertyValue('text-transform') == "uppercase";
).forEach((elm) ->
if elm.value
elm.value = elm.value.toUpperCase()
else
$elm = $(elm)
$elm.html($elm.html().toUpperCase())
)
这不是很好,无论想象力如何,但它都有效。
我不应该在这里做两件事,并且可能会改变:劫持toUpperCase()
并且具有不解析标签的特定规则。仍然愿意接受更好的建议!
答案 4 :(得分:1)
这对希腊字符没有帮助,但我很想知道找到具有给定css属性的所有元素。 我对此进行了设置:http://jsfiddle.net/pQfUv/1/
你感兴趣的一点是:
$('*').each(function() {
if ($(this).css('text-transform') == 'uppercase') {
//Do Stuff to the element
}
});
但是,循环遍历所有元素可能是一件相当昂贵的事情。 希望它有所帮助。
干杯, 异
答案 5 :(得分:1)
我可以向你保证,不仅希腊语受到影响。您肯定遇到德语Sharp S和土耳其语letters i的问题。
我不确定使用这些转换的目的是什么,但请记住,许多语言都是使用没有大写和小写字符概念的脚本编写的。如果您使用它来强调,我建议完全删除所有变换,只需用正确的大小写一部分文本。这样翻译人员就可以决定强调单词或句子的方式。
顺便说一句。在特定类的翻译中允许 span 元素也可能是一个好主意 - 这样有人可能会使用ie颜色来区分不同的文本(虽然它不会真正帮助色盲的人。)< / p>
答案 6 :(得分:1)
我觉得Otovo的答案是最优雅,最快捷的。我当然不建议扫描text-transform
的所有元素。对于移动设备上的大页面,速度效率低下是值得注意的。
因此,我建议您只记下CSS文件中包含text-transform
的所有选择器。对于大多数情况,这应该是可能的。然后,直接在这些选择器上使用jQuery。
所以,为了扩展Otovo的答案,在每个语言中添加一个像i18n-el
这样的独特类,就像在body
中一样(这是Drupal的默认值,但任何类似的东西都可以工作)。然后运行:
$('.i18n-el').find('.all-relevant-selectors').attr('lang', 'el');
明显用您在CSS文件中记下的选择器替换.all-relevant-selectors
,用逗号分隔。
另外,值得一提的是,这仅适用于{39}而非text-transform: uppercase
适用于Chrome 39。
或者,有一个名为jquery-remove-upcase-accents的jQuery插件,虽然我根本没有评估它。