Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/417.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaScript:如何检查字符是否为RTL?_Javascript_Unicode_Right To Left_Bidi - Fatal编程技术网

JavaScript:如何检查字符是否为RTL?

JavaScript:如何检查字符是否为RTL?,javascript,unicode,right-to-left,bidi,Javascript,Unicode,Right To Left,Bidi,如何以编程方式检查浏览器是否将某些字符视为JavaScript中的RTL 也许创建一些透明的DIV并查看文本的放置位置 一点上下文。Unicode 5.2增加了对Avestan字母表的支持。因此,如果浏览器支持Unicode 5.2,它会将U+10B00等字符视为RTL(目前只有Firefox支持)。否则,它将这些字符视为LTR,因为这是默认值 如何以编程方式检查此问题?我正在编写一个Avestan输入脚本,如果浏览器太笨,我想覆盖bidi方向。但,若浏览器确实支持Unicode,则不应覆盖bi

如何以编程方式检查浏览器是否将某些字符视为JavaScript中的RTL

也许创建一些透明的DIV并查看文本的放置位置

一点上下文。Unicode 5.2增加了对Avestan字母表的支持。因此,如果浏览器支持Unicode 5.2,它会将U+10B00等字符视为RTL(目前只有Firefox支持)。否则,它将这些字符视为LTR,因为这是默认值

如何以编程方式检查此问题?我正在编写一个Avestan输入脚本,如果浏览器太笨,我想覆盖bidi方向。但,若浏览器确实支持Unicode,则不应覆盖bidi设置(因为这将允许混合使用Avestan和西里尔文)

我现在这样做:

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之后,这会使脚本的可用性降低。

首先解决标题中的问题:

JavaScript中没有用于访问字符Unicode属性的工具。您需要为此目的找到一个库或服务(如果您需要可靠的东西,恐怕这可能很困难),或者从Unicode字符“数据库”(特定格式的文本文件集合)中提取相关信息,并编写自己的代码来使用它

然后是消息正文中的问题:


这似乎更令人绝望。但是,由于这可能是为数不多的熟悉Avestan的用户所做的事情,因此以适当的方向显示一串Avestan字符和它们的图像,并要求用户单击按钮(如果顺序错误),可能不会太糟糕。您可以将此选择保存在cookie中,这样用户只需执行一次(每个浏览器;虽然它应该是相对较短的cookie,因为浏览器可能会更新)。

谢谢您的评论,但似乎我自己也这么做了:

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('
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);
};
Avestan在document.write中(是脚本)

我意识到在最初的问题被问到和回答之后,这已经是相当长的一段时间了,但我发现vsync的更新非常有用,只是想添加一些观察。我想在他的回答中添加这一点,但我的声誉还不够高

与其使用正则表达式从第0行或更多非LTR字符开始搜索,然后再搜索一个RTL字符,不如从第0行或更多弱/中性字符开始搜索,然后再搜索一个RTL字符。否则,可能会不必要地匹配许多RTL字符我希望对我的弱/中性字符组进行更彻底的检查,因为我只使用了LTR和RTL组合字符组的否定

此外,诸如LTR/RTL标记、嵌入、覆盖等字符不应该包含在适当的字符分组中吗

我认为最终的代码应该是这样的:

function isRTL(s){           
    var rtlChars        = '\u0591-\u07FF\u200F\u202B\u202E\uFB1D-\uFDFD\uFE70-\uFEFC',
        rtlDirCheck     = new RegExp('^[^'+rtlChars+']*?['+rtlChars+']');

    return rtlDirCheck.test(s);
};
更新 可能有一些方法可以加快上述正则表达式的速度。使用带惰性量词的否定字符类似乎有助于提高速度(在网站上测试,需要Silverlight 5)

此外,如果字符串的方向未知,我的猜测是,在大多数情况下,字符串将是LTR而不是RTL,如果是这种情况,则创建
isLTR
函数将更快返回结果,但由于OP要求
isRTL
,因此将提供
isRTL
函数:

/[\u0590-\u06FF]/.test(textarea.value)

测试希伯来语和阿拉伯语(我知道的唯一一种从右向左流动的现代RTL语言/字符集,除了我没有研究过的任何与波斯语相关的语言):

更多的研究表明:


您无法以编程方式检查浏览器如何呈现特定角色。这可能是由于底层操作系统造成的,或者浏览器可能有自己的呈现代码(例如,我认为Windows上的Safari不使用Windows OS文本呈现器)。如果幸运的话,您可能会找到一个资源,告诉您每个浏览器的哪个版本支持哪个版本的Unicode。您可以检查给定的字符是否为RTL,但您必须找到JavaScript Unicode库或从和获取数据
。有17种语言是RTL,所以你可以检查
keydown
事件的
keyCode
,如果与这17种语言的keycodes的范围相匹配……我知道这不是一件很难做到的事情。但是,我希望能以某种方式完成。我目前正在签入g如果我可以创建一个有两个跨距的隐藏div,获取它们的边界矩形并比较X坐标。如果这样做有效,我将在这里介绍。是的,在页面元素布局上测量是我能想到的检测支持的唯一方法。我建议使用
offsetLeft
而不是
getBoundingClientRect
,因为浏览器支持更好。T汉克斯,我打算用它。但我发现了另一个问题:Opera在页面上以RTL的形式布局Avestan,但在文本区域中以LTR的形式布局Avestan!:(对我来说,测量div似乎很疯狂……正则表达式似乎是唯一的方法,谷歌的搜索页面也同意。去google.com,粘贴一些RTL,然后麦克风图标翻转。查看源代码,他们使用(更复杂/完整吗?)正则表达式。@Javid-我不记得了。为什么?@vsync我对它很好奇。你有没有深入研究Unicode文档或者从其他地方复制它呢?@Javid-我可能在另一个地方找到了这些代码,并围绕着它构建了代码。就像5年前一样,所以我真的不记得太多。你问这个问题是因为你认为某位同事des可能丢失了?我在这里找到了文档:您可以在jsPERF上测试它。顺便说一句,我已经测试了您的函数,但它们不起作用……您可以在我的游乐场页面上测试它们,在我的回答中。
/[\u0590-\u06FF]/.test(textarea.value)
/[\u0590-\u07FF\u200F\u202B\u202E\uFB1D-\uFDFD\uFE70-\uFEFC]/.test(textarea.value)