23

ブラウザがJavaScriptで一部の文字をRTLとして処理するかどうかをプログラムで確認するにはどうすればよいですか?

透明なDIVを作成して、テキストが配置されている場所を確認しているのではないでしょうか。

少しコンテキスト。Unicode 5.2では、アヴェスター文字のサポートが追加されました。したがって、ブラウザがUnicode 5.2をサポートしている場合、U + 10B00のような文字をRTLとして扱います(現在はFirefoxのみがサポートしています)。それ以外の場合は、これがデフォルトであるため、これらの文字をLTRとして扱います。

これをプログラムで確認するにはどうすればよいですか?私はAvestan入力スクリプトを書いていますが、ブラウザーがあまりにも馬鹿げている場合は、bidiの方向をオーバーライドしたいと思います。ただし、ブラウザがUnicodeをサポートしている場合は、双方向設定を上書きしないでください(これにより、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のサポートを開始した後、スクリプトが使いにくくなります。

4

5 に答える 5

31
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-02-12T03:09:29.203 に答える
8

元の質問が出されて答えられてからかなり時間が経っていることに気づきましたが、vsyncの更新はかなり有用であることがわかり、いくつかの所見を追加したかっただけです。私はこれを彼の答えにコメントで追加しますが、私の評判はまだ十分に高くありません。

行の先頭から0個以上の非LTR文字を検索してから1つのRTL文字を検索する正規表現の代わりに、行の先頭から0個以上の弱い/中立文字を検索してから検索する方が理にかなっています。 1つの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が必要です)

さらに、文字列の方向性が不明な場合、ほとんどの場合、文字列はRTLではなくLTRになり、isLTR関数を作成すると結果が速く返されますが、OPが要求しているように、関数isRTLを提供します。isRTL

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

    return rtlDirCheck.test(s);
};
于 2013-10-02T17:38:28.503 に答える
3

ヘブライ語とアラビア語の両方のテスト(私が調査していないペルシア語関連を除いて、右から左に流れるのは私が知っている唯一の最新のRTL言語/文字セット):

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

より多くの研究は、次の線に沿って何かを示唆しています:

/[\u0590-\u07FF\u200F\u202B\u202E\uFB1D-\uFDFD\uFE70-\uFEFC]/.test(textarea.value)
于 2016-11-01T02:15:09.690 に答える
2

最初に見出しの質問に対処します。

JavaScriptには、文字のUnicodeプロパティにアクセスするためのツールはありません。目的のためにライブラリまたはサービスを見つける必要があります(信頼できるものが必要な場合は難しいかもしれません)、またはUnicode文字の「データベース」(特定の形式のテキストファイルのコレクション)から関連情報を抽出する必要があります)そしてそれを使用するためにあなた自身のコードを書くこと。

次に、メッセージ本文の質問:

これはさらに必死のようです。しかし、これはおそらくアヴェスター語に精通していて知っている限られた数のユーザーにとっては何かであるため、アヴェスター語の文字列とそれらの画像を適切な方向で表示し、ユーザーにクリックするように依頼することはそれほど悪くないでしょう。順序が間違っている場合はボタン。また、この選択をCookieに保存して、ユーザーがこれを1回だけ実行する必要があるようにすることもできます(ただし、ブラウザーが更新される可能性があるため、比較的短命のCookieである必要があります)。

于 2012-08-17T13:17:16.610 に答える
2

コメントありがとうございますが、私はこれを自分で行ったようです。

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>.

うまくいくようです。:)

于 2012-08-17T15:20:58.440 に答える