2010-09-23 9 views
38

Die Implementierungen der wichtigsten Browser scheinen Probleme mit text-transform: uppercase mit türkischen Zeichen zu haben. Soweit ich weiß (ich bin nicht türkisch.) Gibt es vier verschiedene i Zeichen: ı i I İ wo die letzten beiden sind die Großbuchstaben Darstellungen der ehemaligen zwei.CSS: Text-Transformation funktioniert nicht richtig für türkische Zeichen

Anwendung jedoch text-transform:uppercase-ı i, der Browser (geprüft IE, Firefox, Chrome und Safari) Ergebnisse in I I, die nicht korrekt ist, und kann die Bedeutung der Worte ändern, so sehr, dass sie beleidigt werden. (Das ist, was ich gesagt habe)

Da meine Forschung für Lösungen nicht meine Frage ergeben hat ist: Gibt es für dieses Problem Workarounds? Die erste Problemumgehung könnte sein, text-transform: uppercase vollständig zu entfernen, aber das ist eine Art letzter Ausweg.

Lustige Sache, das W3C hat Tests für dieses Problem auf ihrer Website, aber Mangel an weiteren Informationen zu diesem Problem. http://www.w3.org/International/tests/tests-html-css/tests-text-transform/generate?test=5

schätzen ich Hilfe und freuen uns auf Ihre Antworten zu suchen :-)

Hier ist ein codepen

+0

Können Sie eine Arbeits zeigen, äh, nicht-funktionierendes Beispiel für Ihren Fall? – Tim

+0

Sicher, schau mal unter http://malax.de/turkish-css-text-transform.html – Malax

+0

Link funktioniert nicht mehr, ja. –

Antwort

56

können Sie lang Attribut hinzufügen und seinen Wert auf tr gesetzt, dies zu lösen:

<html lang="tr"> oder <div lang="tr">

Here is working example.

+1

Dies sollte heute die akzeptierte Antwort sein. – gok

+1

Ich habe Probleme damit. Es funktioniert perfekt auf dem Desktop sowohl mit Chrome und Safari. IOS-Browser scheinen dieses Tag jedoch zu ignorieren. Scheitert es auf mobilen Chrome und mobilen Safari, irgendwelche Ideen? – gok

+0

ok, anscheinend ist es problematisch mit iOS 7 ~, es funktioniert auf iOS 8 ~ – gok

0

Die Ursache für dieses Problem eine falsche Handhabung dieser türkischen Zeichen von Unicode-Bibliothek in all diese verwendet werden müssen Browser. Daher bezweifle ich, dass es dafür eine Korrektur auf der Vorderseite gibt.

Jemand muss dieses Problem den Entwicklern dieser Unicode-Bibliotheken melden, und es würde in einigen Wochen/Monaten behoben werden.

+0

Deshalb frage ich nach Workarounds, nicht nach Fixes.;-) – Malax

+0

Sie behandeln sie nicht falsch, sie wissen einfach nicht, dass es Türkisch heißt. – tdammers

+0

Wochen/Monate? Versuche Jahre/Jahrzehnte. Ich habe dafür offene Bugs für Firefox und Safari gefunden: https://bugzilla.mozilla.org/show_bug.cgi?id=231162 https://bugs.webkit.org/show_bug.cgi?id=21312 – gtd

0

Wenn Sie sich nicht auf Text-Transformation und Browser verlassen können, müssen Sie Ihren Text in Großbuchstaben selbst auf dem Server rendern (ich hoffe, dass Sie den Text nicht vergrößern, wie der Benutzer ihn eingibt). Sie sollten dort die Internationalisierung besser unterstützen.

0

Diese Problemumgehung erfordert etwas Javascript. Wenn Sie das nicht tun wollen, aber etwas Serverseite haben, die den Text vorverarbeiten kann, wird diese Idee auch dort funktionieren (denke ich).

Zuerst erkennen, ob Sie auf Türkisch laufen. Wenn dies der Fall ist, scannen Sie alles, was in Großbuchstaben geschrieben wird, um festzustellen, ob es die problematischen Zeichen enthält. Wenn dies der Fall ist, ersetzen Sie alle diese Zeichen durch ihre Großbuchstaben. Wenden Sie dann das CSS in Großbuchstaben an. Da die problematischen Zeichen bereits Großbuchstaben sind, sollte das ein total feines (Ghetto) umgehen. Für Javascript stelle ich mir vor, mit einigen .innerHTML auf Ihren betroffenen Elementen zu arbeiten.

Lassen Sie mich wissen, wenn Sie irgendwelche Details der Implementierung benötigen, ich habe eine gute Vorstellung davon, wie dies in Javascript tun Methoden Javascript String-Manipulation verwendet. Diese allgemeine Idee sollten Sie die meisten der Weg dorthin kommt (und mich hoffentlich eine Prämie!)

-Brian J. Stinar-

14

Hier ist eine schnelle und schmutzige Abhilfe Beispiel - es ist schneller als ich dachte (getestet in ein Dokument mit 2400 Tags -> keine Verzögerung.Aber ich sehe, dass js Abhilfen sind nicht die beste Lösung

<html> 
<head> 
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-3"> 
</head> 
<body> 
<div style="text-transform:uppercase">a b c ç d e f g ğ h ı i j k l m n o ö p r s ş t u ü v y z (source)</div> <div>A B C Ç D E F G Ğ H I İ J K L M N O Ö P R S Ş T U Ü V Y Z (should be like this)</div> 

<script> 
    function getStyle(element, style) { 
     var result; 

     if (document.defaultView && document.defaultView.getComputedStyle) { 
      result = document.defaultView.getComputedStyle(element, '').getPropertyValue(style); 
     } else if(element.currentStyle) { 
      style = style.replace(/\-(\w)/g, function (strMatch, p1) { 
       return p1.toUpperCase(); 
      }); 
      result = element.currentStyle[style]; 
     } 
     return result; 
    } 

    function replaceRecursive(element) { 
     if (element && element.style && getStyle(element, 'text-transform') == 'uppercase') { 
      element.innerHTML = element.innerHTML.replace(/ı/g, 'I'); 
      element.innerHTML = element.innerHTML.replace(/i/g, 'İ'); // replaces 'i' in tags too, regular expression should be extended if necessary 
     } 

     if (!element.childNodes || element.childNodes.length == 0) return; 

     for (var n in element.childNodes) { 
      replaceRecursive(element.childNodes[n]); 
     } 
    } 

    window.onload = function() { // as appropriate 'ondomready' 
     alert('before...'); 
     replaceRecursive(document.getElementsByTagName('body')[0]); 
     alert('...after'); 
    } 
</script> 

</body> 
</html> 
+0

Ich mag Ihre Implementierung von nur den gesamten Inhalt in der Oberklasse, anstatt die spezifischen Zeichen zu ersetzen und auf CSS angewiesen, wie ich vorgeschlagen habe. Ich habe eine Frage zu Ihrer rekursiven Ersetzung und .innerHTML, vor allem, weil ich dieses Attribut nicht gut genug verstehe. Wenn ich Elemente

contents
verschachtelt habe, und ich Ihre replaceRecursive() aufrufen, wird die IDs in der Oberklasse sein? Danke, dass Sie mir geholfen haben, Ihre Implementierung zu verstehen. –

+5

Sie könnten Tests für 'lang =" tr "' hinzufügen und sollten '' in ... 'definitiv nicht verwenden, um 'NodeList' Objekte zu durchlaufen: https://developer.mozilla.org/D/D/ NodeList. Sonst, +1 –

+0

Gute Punkte Yi, auch dies funktioniert nicht mit gemischten Element/Text-Kind-Knoten (wie wenn Sie eine Beschriftung haben, die ein Eingabefeld und seine Beschreibung umschließt). Ich habe alle diese Probleme behoben und habe eine Lösung, die ich in der Produktion verwende, die ich als separate Antwort weitergeben werde. – gtd

7

Hier ist meine erweiterte Version von alex Code, den ich in der Produktion bin mit:

(function($) { 
    function getStyle(element, style) { 
    var result; 

    if (document.defaultView && document.defaultView.getComputedStyle) { 
     result = document.defaultView.getComputedStyle(element, '').getPropertyValue(style); 
    } else if(element.currentStyle) { 
     style = style.replace(/\-(\w)/g, function (strMatch, p1) { 
     return p1.toUpperCase(); 
     }); 
     result = element.currentStyle[style]; 
    } 
    return result; 
    } 

    function replaceRecursive(element, lang) { 
    if(element.lang) { 
     lang = element.lang; // Maintain language context 
    } 

    if (element && element.style && getStyle(element, 'text-transform') == 'uppercase') { 
     if (lang == 'tr' && element.value) { 
     element.value = element.value.replace(/ı/g, 'I'); 
     element.value = element.value.replace(/i/g, 'İ'); 
     } 

     for (var i = 0; i < element.childNodes.length; ++i) { 
     if (lang == 'tr' && element.childNodes[i].nodeType == Node.TEXT_NODE) { 
      element.childNodes[i].textContent = element.childNodes[i].textContent.replace(/ı/g, 'I'); 
      element.childNodes[i].textContent = element.childNodes[i].textContent.replace(/i/g, 'İ'); 
     } else { 
      replaceRecursive(element.childNodes[i], lang); 
     } 
     } 
    } else { 
     if (!element.childNodes || element.childNodes.length == 0) return; 

     for (var i = 0; i < element.childNodes.length; ++i) { 
     replaceRecursive(element.childNodes[i], lang); 
     } 
    } 
    } 

    $(document).ready(function(){ replaceRecursive(document.getElementsByTagName('html')[0], ''); }) 
})(jQuery); 

Bitte beachte, dass ich jQuery benutze hier nur für die ready() Funktion. Der jQuery-Kompatibilitäts-Wrapper ist auch eine bequeme Möglichkeit, die Funktionen mit einem Namespace zu versehen. Ansonsten sind die beiden Funktionen nicht auf jQuery angewiesen, so dass Sie sie herausziehen können.

Im Vergleich zur Originalversion alex löst dies ein paar Probleme:

  • Es verfolgt das Attribut lang, wie es recurses durch, denn wenn Sie türkische und anderer lateinischer Inhalt gemischt haben, werden Sie falsche Transformationen erhalten auf dem Nicht-Türkisch ohne es. In diesem Sinne gebe ich die Basis html Element, nicht die body. Sie können lang="en" auf einem beliebigen Tag, das nicht türkisch ist, kleben, um eine unzulässige Großschreibung zu verhindern.

  • Sie wendet die Umwandlung nur auf TEXT_NODES an, da die vorherige innerHTML-Methode nicht mit gemischten Text/Element-Knoten wie Beschriftungen mit Text und Kontrollkästchen in ihnen funktioniert hat.

Während einige bemerkenswerte Mängel im Vergleich mit auf eine serverseitige Lösung, es hat auch einige große Vorteile, von denen der Chef Abdeckung ohne serverseitige gewährleistet ist, die sich bewusst sein, welche Arten angewendet werden, welche Inhalte . Wenn einer der Inhalte indiziert und in Google-Zusammenfassungen angezeigt wird (z. B.), ist es viel besser, wenn er bei der Schaltung in Kleinbuchstaben bleibt.

+0

Danke für das Posten! :) – Malax

+1

Danke für die Frage ein Jahr bevor ich es brauchte :) – gtd

4

Die nächste Version von Firefox Nightly (die Firefox 14 werden sollte) hat eine Lösung für dieses Problem und sollte den Fall ohne jeden Hack behandeln (wie die CSS3-Spezifikationen es anfordern).

Die blutigen Details sind in diesem Fehler zur Verfügung: https://bugzilla.mozilla.org/show_bug.cgi?id=231162

Sie Ich denke auch, das Problem für font-variant fixiert (Für diejenigen, nicht zu wissen, was font-variant der Fall ist, sehen https://developer.mozilla.org/en/CSS/font-variant, noch nicht up-to-date mit der Änderung, aber der doc ist browserunabhängig und ein Wiki, so ...)

+0

Schöne Follow-up, danke! – Malax

0

Sie können dies mit nativer javascript aswell lösen:

Here is also its gist.

String.prototype.turkishToLower = function(){ 
 
    var string = this; 
 
    var letters = { "İ": "i", "I": "ı", "Ş": "ş", "Ğ": "ğ", "Ü": "ü", "Ö": "ö", "Ç": "ç" }; 
 
    string = string.replace(/(([İIŞĞÜÇÖ]))/g, function(letter){ return letters[letter]; }) 
 
    return string.toLowerCase(); 
 
} 
 

 
String.prototype.turkishToUpper = function(){ 
 
    var string = this; 
 
    var letters = { "i": "İ", "ş": "Ş", "ğ": "Ğ", "ü": "Ü", "ö": "Ö", "ç": "Ç", "ı": "I" }; 
 
    string = string.replace(/(([iışğüçö]))/g, function(letter){ return letters[letter]; }) 
 
    return string.toUpperCase(); 
 
} 
 

 
var text = 'iii'; 
 
text = text.turkishToUpper(); 
 
console.log(text);