57

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

然而应用text-transform:uppercaseı i,浏览器(检查 IE、Firefox、Chrome 和 Safari)的结果I I是不正确的,并且可能会改变单词的含义,以至于它们成为侮辱。(这是我被告知的)

由于我对解决方案的研究没有发现任何问题,因此我的问题是:是否有解决此问题的方法?第一个解决方法可能是text-transform: uppercase完全删除,但这是最后的手段。

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

感谢您的帮助并期待您的回答:-)

这是一个代码笔

4

7 回答 7

95

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

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

这是工作示例。

于 2014-03-24T10:17:37.663 回答
15

这是一个快速而肮脏的解决方法示例-它比我想象的要快(在具有 2400 个标签的文档中测试-> 无延迟)。但我看到 js 变通办法不是最好的解决方案

<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>
于 2010-10-01T08:06:06.867 回答
7

这是我在生产中使用的 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);

请注意,我在这里仅将 jQuery 用于该ready()功能。jQuery 兼容性包装器也是命名函数的便捷方式。除此之外,这两个函数根本不依赖 jQuery,所以你可以把它们拉出来。

与 alex 的原始版本相比,这个版本解决了几个问题:

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

  • 它仅适用于转换,TEXT_NODES因为以前的innerHTML方法不适用于混合文本/元素节点,例如带有文本的标签和其中的复选框。

虽然与服务器端解决方案相比有一些明显的缺陷,但它也有一些主要优点,主要优点是保证覆盖率,而服务器端不必知道哪些样式应用于哪些内容。如果任何内容被编入索引并显示在 Google 摘要中(例如),那么在提供时保持小写会更好。

于 2012-01-05T13:13:25.857 回答
4

Firefox Nightly 的下一个版本(应该成为 Firefox 14)修复了这个问题,并且应该在没有任何 hack 的情况下处理这个问题(正如 CSS3 规范所要求的那样)。

该错误中提供了血腥细节:https ://bugzilla.mozilla.org/show_bug.cgi?id=231162

他们还解决了我认为 font-variant 的问题(对于那些不知道 font-variant 做什么的人,请参阅https://developer.mozilla.org/en/CSS/font-variant,尚未与更改,但文档与浏览器无关且是 wiki,所以...)

于 2012-03-29T20:21:40.230 回答
0

If you can't rely on text-transform and browsers you will have to render your text in uppercase yourself on the server (hope you're not uppercasing the text as the user types it). You should have a better support for internationalisation there.

于 2010-09-29T15:44:11.790 回答
0

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

必须有人向这些 un​​icode 库的开发人员报告此问题,并且它将在几周/几个月内修复。

于 2010-09-28T15:27:34.170 回答
0

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

首先,检测您是否在土耳其语中运行。如果你是,然后扫描你要大写的任何内容,看看它是否包含问题字符。如果是这样,请将所有这些字符替换为它们的大写版本。然后应用大写的 CSS。由于问题字符已经是大写的,这应该是一个完全可以解决的问题(ghetto)。对于 Javascript,我设想必须在受影响的元素上处理一些 .innerHTML。

如果您需要任何实现细节,请告诉我,我很清楚如何使用 Javascript 字符串操作方法在 Javascript 中执行此操作。这个一般的想法应该能让你大部分时间到达那里(并希望给我一个赏金!)

-Brian J. Stinar-

于 2010-09-29T16:46:10.323 回答