2012-02-24 67 views
12

我已經寫了包含幾種語言的翻譯Web應用程序希臘和文本轉換:(他們是希臘的一個)大寫

當顯示的標題一定的翻譯,設計規則是,文本應該是大寫的,在世界上任何其他語言都是好的,但是對於希臘語,瀏覽器不知道如何處理這些重音(見this),因此它們顯示錯誤的大寫字符串。

從上面鏈接的補丁中,我已經將它轉換爲Javascript,運行了一些用例,並且它可以工作。現在我所要做的就是:

如果不需要爲需要大寫的每個元素添加uppercase類,那麼我可以使用計算樣式屬性來查詢DOM嗎? IE瀏覽器。給我所有的有一個計算text-transform: uppercase

回答

10

。而是這樣做:

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. 
    } 
} 

測試了10000個元素,其中2500個「大寫」文本轉換。

jQuery processed in 595ms
JS processed in 60ms

因此,JavaScript比jQuery快大約10倍。

編輯:另一個測試,這次10萬組的元素:

jQuery failed.TypeError: Object doesn't support property or method 'each'
JS processed in 577ms

+0

不錯!將更新:-) – changelog 2012-02-24 17:38:57

+0

我應該在哪裏放置這段代碼? – zekia 2016-05-09 14:22:50

3

OK的元素,僅供參考,這裏是我的解決方案迄今:

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) 

這是在上面的錯誤提供的補丁咖啡劇本改編。

這是我做的一個觀點之後被渲染:

# 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()並且有特定的規則來解析標籤。仍然打開更好的建議!

1

這不會對希臘字符有幫助,但我很好奇尋找具有給定css屬性的所有元素。 我此設置:http://jsfiddle.net/pQfUv/1/

會感興趣,你將是位:

$('*').each(function() { 
      if ($(this).css('text-transform') == 'uppercase') { 
       //Do Stuff to the element 
      } 
     }); 

通過所有的元素循環可能是相當昂貴的事情,雖然。 希望它有幫助。

乾杯, ISO我強烈建議不使用jQuery這個

1

我可以向你保證,不僅希臘會受到影響。德國Sharp S和土耳其letters i肯定有問題。

我不確定使用這些轉換的目的是什麼,但請記住,許多語言都是用沒有大寫和小寫字符概念的腳本編寫的。如果您將此用於強調,我建議完全刪除所有轉換,並簡單地用適當的大小寫部分文本。這樣翻譯人員可以決定如何強調單詞或句子。

順便說一句。允許跨度在翻譯中的元素與特定的類也可能是一個好主意 - (雖然它不會真正幫助色盲的人)的方式有人可能會使用即顏色不同的標記文本

3

我使用此PHP函數:

function toUpper($str){ 
     $search = array('Ά', 'Έ', 'Ί', 'Ή', 'Ύ', 'Ό', 'Ώ'); 
     $replace = array('Α', 'Ε', 'Ι', 'Η', 'Υ', 'Ο', 'Ω'); 
     $str = mb_strtoupper($str, "UTF-8"); 
     return str_replace($search, $replace, $str); 
    } 
+0

你的方法存在的問題是它並不那麼簡單。先前的2個或前3個字母有一些變化。 – changelog 2012-04-17 12:52:55

+0

我不明白你的意思是說實話。我發佈的函數將所有沒有壓力標記的字母大寫,並且其餘部分使用str_replace。現在,作爲一個希臘人相信我,這是一個服務器端的方法,我發佈它,因爲你說你正在使用PHP。現在,我已經在幾個網站中使用過它,沒有任何問題。以前的信件與它無關。既然是我的母語,我會知道它是否會錯誤地翻譯錯誤! :p P.S. <3葡萄牙! :) – 2012-04-17 13:03:50

+0

我從這裏得到了我的解決方案的內部工作原理:https://bug307039.bugzilla.mozilla.org/attachment.cgi?id=588764 我沒有使用PHP(我在服務器端使用Ruby ),這是一個演示規則,所以它適合Javascript。這個補丁是否錯誤?我應該用簡單的東西來取代我所擁有的東西嗎? – changelog 2012-04-17 13:13:30

11

在這個問題的解決方案實施例3 here

This is an example如上所述,應該在任何瀏覽器中工作(只測試在火狐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

非常有幫助的回答,upvoted! – Elio 2014-04-16 11:10:04

+3

在IE和Chrome中不起作用,對於Chrome,如果您將lang =「el」添加到html標記,它將起作用 – 2014-05-21 14:57:00

1

我喜歡Otovo的回答是最優雅,快速。我當然不會推薦掃描所有元素爲text-transform。對於移動設備上的大頁面,速度效率不高是顯着的。

因此,我會建議只需從CSS文件中記下所有選擇器text-transform。這在大多數情況下應該是可能的。然後,直接在這些選擇器上使用jQuery。

因此,要擴展Otovo的答案,請在body(這是Drupal的默認設置,但任何類似的工作)的地方添加每種語言的i18n-el等獨特類。然後運行:

$('.i18n-el').find('.all-relevant-selectors').attr('lang', 'el'); 

Obviouslt與您從CSS文件中記下的選擇,用逗號分隔取代.all-relevant-selectors

此外,值得一提的是,這僅適用於text-transform: uppercase而不是font-variant: small-caps爲Chrome 39

另外,還有一個jQuery插件這個事情叫做jquery-remove-upcase-accents,雖然我還沒有評估它。