如何以编程方式检查浏览器是否将某个字符视为JavaScript中的RTL?
也许可以创建一些透明的DIV,看看文本放在哪里?
有一点上下文。 Unicode 5.2增加了对阿维斯坦字母表的支持。因此,如果浏览器支持Unicode5.2,那么它将像U+10B00这样的字符作为RTL来处理(目前只有Firefox这样做)。否则,它将这些字符视为LTR,因为这是默认的。
如何以编程方式检查这一点?我正在编写一个Avestan输入脚本,如果浏览器太笨,我想重写bidi方向。但是,如果浏览器确实支持Unicode,则bidi设置不应该被覆盖(因为这将允许将Avestan和Cyrillic混合在一起)。
我现在这样做:
var ua = navigator.userAgent.toLowerCase();
if (ua.match('webkit') || ua.match('presto') || ua.match('trident')) {
var input = document.getElementById('orig');
if (input) {
input.style.direction = 'rtl';
input.style.unicodeBidi = 'bidi-override';
}
}
但是,很明显,在Chrome和Opera开始支持Unicode 5.2之后,这会使脚本的可用性降低。
发布于 2012-08-17 15:20:58
谢谢你的评论,但似乎我自己也这么做了:
function is_script_rtl(t) {
var d, s1, s2, bodies;
//If the browser doesn’t support this, it probably doesn’t support Unicode 5.2
if (!("getBoundingClientRect" in document.documentElement))
return false;
//Set up a testing DIV
d = document.createElement('div');
d.style.position = 'absolute';
d.style.visibility = 'hidden';
d.style.width = 'auto';
d.style.height = 'auto';
d.style.fontSize = '10px';
d.style.fontFamily = "'Ahuramzda'";
d.appendChild(document.createTextNode(t));
s1 = document.createElement("span");
s1.appendChild(document.createTextNode(t));
d.appendChild(s1);
s2 = document.createElement("span");
s2.appendChild(document.createTextNode(t));
d.appendChild(s2);
d.appendChild(document.createTextNode(t));
bodies = document.getElementsByTagName('body');
if (bodies) {
var body, r1, r2;
body = bodies[0];
body.appendChild(d);
var r1 = s1.getBoundingClientRect();
var r2 = s2.getBoundingClientRect();
body.removeChild(d);
return r1.left > r2.left;
}
return false;
}
使用示例:
Avestan in <script>document.write(is_script_rtl('') ? "RTL" : "LTR")</script>,
Arabic is <script>document.write(is_script_rtl('العربية') ? "RTL" : "LTR")</script>,
English is <script>document.write(is_script_rtl('English') ? "RTL" : "LTR")</script>.
好像很管用。:)
发布于 2013-02-12 03:09:29
function isRTL(s){
var ltrChars = 'A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02B8\u0300-\u0590\u0800-\u1FFF'+'\u2C00-\uFB1C\uFDFE-\uFE6F\uFEFD-\uFFFF',
rtlChars = '\u0591-\u07FF\uFB1D-\uFDFD\uFE70-\uFEFC',
rtlDirCheck = new RegExp('^[^'+ltrChars+']*['+rtlChars+']');
return rtlDirCheck.test(s);
};
发布于 2013-10-02 17:38:28
我意识到这是在最初的问题被问到并回答之后很长一段时间了,但是我发现vsync的更新相当有用,只是想添加一些观察。我想在他的回答中加上这一点,但我的声誉还不够高。
不是从行零或多个非LTR字符开始搜索的正则表达式,然后是一个RTL字符,从行零或多个弱/中性字符开始搜索,然后再搜索一个RTL字符,不是更有意义吗?否则,您就有可能不必要地匹配许多RTL字符。我欢迎对我的弱/中性字符组进行更彻底的检查,因为我只是使用了对LTR和RTL组合字符组的否定。
此外,诸如LTR/RTL标记、嵌入、重写等字符不应该包含在适当的字符组中吗?
因此,我认为最后的代码应该类似于:
function isRTL(s){
var weakChars = '\u0000-\u0040\u005B-\u0060\u007B-\u00BF\u00D7\u00F7\u02B9-\u02FF\u2000-\u2BFF\u2010-\u2029\u202C\u202F-\u2BFF',
rtlChars = '\u0591-\u07FF\u200F\u202B\u202E\uFB1D-\uFDFD\uFE70-\uFEFC',
rtlDirCheck = new RegExp('^['+weakChars+']*['+rtlChars+']');
return rtlDirCheck.test(s);
};
更新
可能有一些方法可以加快上述正则表达式的速度。使用带有惰性量词的否定字符类似乎有助于提高速度(在http://regexhero.net/tester/?id=6dab761c-2517-4d20-9652-6d801623eeec上测试,站点需要Silverlight 5)
此外,如果字符串的方向性未知,我猜在大多数情况下,字符串将是LTR而不是RTL,如果是这样的话,创建isLTR
函数会更快地返回结果,但正如OP要求的那样,将提供isRTL
函数:
function isRTL(s){
var rtlChars = '\u0591-\u07FF\u200F\u202B\u202E\uFB1D-\uFDFD\uFE70-\uFEFC',
rtlDirCheck = new RegExp('^[^'+rtlChars+']*?['+rtlChars+']');
return rtlDirCheck.test(s);
};
https://stackoverflow.com/questions/12006095
复制相似问题