CSS:文本转换不正确的土耳其人物

主要浏览器的实现似乎有text-transform: uppercase问题text-transform: uppercase土耳其字符text-transform: uppercase 。 据我所知(我不是土耳其人),有四个不同的i字符: ı i I İ最后两个是前两个大写字母表示。

然而,应用text-transform:uppercaseı i ,浏览器(检查的IE浏览器,火狐浏览器, text-transform:uppercase ı i浏览器和Safari浏览器)导致II ,这是不正确的,可能会改变这些词的含义太多,使他们成为侮辱。 (这就是我所知道的)

正如我对解决scheme的研究没有透露任何我的问题是:有这个问题的解决方法吗? 第一个解决方法可能是彻底删除text-transform: uppercase但这是某种最后的手段。

有趣的是,W3C已经在他们的网站上testing了这个问题,但是缺乏关于这个问题的更多信息。 http://www.w3.org/International/tests/tests-html-css/tests-text-transform/generate?test=5

我感谢任何帮助,期待你的回答:-)

这是一个codepen

您可以添加lang属性并将其值设置为tr来解决此问题:

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

这是工作的例子。

这是一个快速和肮脏的解决方法示例 – 它比我想象的更快(在具有2400个标签的文档中testing – >没有延迟)。 但是我发现js解决方法并不是最好的解决scheme

 <html> <head> <meta http-equiv="content-type" content="text/html; charset=ISO-8859-3"> </head> <body> <div style="text-transform:uppercase">abc ç defg ğ h ı ijklmno ö prs ş tu ü vyz (source)</div> <div>ABC Ç DEFG Ğ HI İ JKLMNO Ö PRS Ş TU Ü VYZ (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> 

这里是我在生产中使用的alex代码的增强版本:

 (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); 

请注意,我在这里只使用ready()函数使用jQuery。 jQuery兼容包装也是一个方便的方法命名空间的function。 除此之外,这两个函数根本不依赖于jQuery,所以你可以把它们拉出来。

与亚历克斯的原始版本相比,这个解决了几个问题:

  • 它会跟踪lang属性的recursion,因为如果你混合了土耳其语和其他拉丁语内容,那么在没有它的情况下你将在非土耳其语中进行不正确的转换。 根据这个我传入基本的html元素,而不是body 。 您可以在任何非土耳其标签上粘贴lang="en"以防止不正确的大小写。

  • 它仅将转换应用于TEXT_NODES因为之前的innerHTML方法不适用于混合的文本/元素节点,如带有文本和checkbox的标签。

与服务器端解决scheme相比,虽然有一些显着的缺陷,但它也有一些主要的优点,其中主要保证覆盖范围,服务器端不必知道什么样式适用于什么内容。 如果有任何内容被编入索引并显示在Google摘要中(例如),如果在服务时保持小写,则会更好。

下一个版本的Firefox Nightly(应该成为Firefox 14)已经解决了这个问题,并且应该在没有任何破解的情况下处理这个问题(就像CSS3规范要求的那样)。

血腥的细节可以在这个错误: https ://bugzilla.mozilla.org/show_bug.cgi?id = 231162

他们还解决了我认为字体变体的问题(对于那些不知道字体变体的用户,请参阅https://developer.mozilla.org/en/CSS/font-variant ,还不是最新的改变,但文档是浏览器不可知的和维基,所以…)

这个问题的根本原因必须是在所有这些浏览器中使用unicode库来处理这些土耳其字符。 所以我怀疑是否有一个前端解决scheme。

有人必须向这些unicode库的开发者报告这个问题,并将在几个星期/几个月内修复。

如果你不能依靠文本转换和浏览器,你将不得不在服务器上以大写forms呈现你的文本(希望你没有在用户input的时候大写文本)。 你应该有更好的国际化支持。

这个解决方法需要一些Javascript。 如果你不想这样做,但有一些服务器端可以预处理文本,这个想法也将在那里工作(我认为)。

首先,检测你是否在土耳其运行。 如果你是,然后扫描你要大写,看看它是否包含问题的字符。 如果他们这样做,将所有这些字符replace为它们的大写版本。 然后应用大写的CSS。 由于问题字符已经是大写,这应该是一个完全正确的(贫民窟)工作。 对于Javascript,我想必须处理一些.inHTML对你的影响的元素。

让我知道如果你需要任何实现的细节,我有一个好主意,如何使用JavaScriptstring操作方法在Javascript中做到这一点。 这个大概的想法应该让你在那里大部分的方式(并希望给我一个赏金!)

-Brian J. Stinar-

你可以用原生的javascript解决这个问题:

这也是它的要点。

 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);