将从左到右书写的语言转换为从右到左书写的HTML。

12
在我的HTML页面中,我需要使文本输入框接受特定集合的字母。为此,我通过捕获键按下事件并检查输入的字符是否有效来实现。
这些允许的字符既来自从左到右书写的英语,也来自少量其他从右到左书写的语言。输入的每个单词可以是英语和希伯来语字母的混合。
我需要让文本框显示从右到左书写的文本(对于英语、希伯来语或阿拉伯语应用相同的行为) - 例如,如果我写下:
A
B
א
ב
C
D
Y
我希望它按照从右到左的顺序呈现。
设置 "style:dir=rtl" 并不能解决问题,它只是将文本呈现为从右到左书写,但实际上不会改变英文字母的呈现顺序以满足我的要求。
最佳方法是什么?
编辑:
看起来这个链接可能解决了我的问题:Right to left Text HTML input,尽管该解决方案没有如我所希望的那样详细解释。

3
可能是 Right to left Text HTML input 的重复问题。 - ElChupacabra
彼得,你的代码在哪里? - Ricky Ruiz
那里没有真正详细的答案,我已经看过那个问题了。@Ricardo,我还没有实施这样的东西。正在努力找到一种方法。 - user5326354
5个回答

10

将您的文本框样式设置为以下内容:

style="direction:rtl; unicode-bidi:bidi-override;"

为什么?

当您只设置文本方向时(使用direction: rtl),在长文本中仍然存在不同的“方向运行”,每个运行都有自己的渲染行为。 "AB" 部分是一个从左到右的运行,这就是为什么您看到它呈现为一个英语单词,B 在 A 的右侧。

添加 unicode-bidi: bidi-override 告诉浏览器忘记那些独立运行,简单地从右到左逐个渲染所有字符。

[添加以应对可能使用数据的客户端应用程序]

对于使用此数据的客户端应用程序,可以以一种方式提供字符串本身,使其能够正确显示,即使这些客户端应用程序不受您控制。

假设客户端应用程序使用某种 API 或服务访问数据(这意味着您不会让它们直接访问您的数据库),则可以在将其发送到客户端之前,在字符串开头添加一个名为Right-to-Left Override(RLO)的 Unicode 控制字符。

RLO 字符代码为 \u202E,因此根据上面的示例,返回给客户端的结果字符串将是:

\u202E

A

B

א

ב

C

D

Y

大多数 Web 浏览器和操作系统都尊重 BiDi 控制字符并应用正确的 BiDi 渲染逻辑。因此,当客户端应用程序将该字符串输出到 UI 时,底层渲染引擎应按您的意图显示字符串。

注意:根据您的平台和编程语言,通过其十六进制代码向字符串添加 Unicode 字符的方式可能会有所不同。


1
文本始终以字符字符串形式保存在数据库中。它的呈现方式取决于显示它的客户端。数据库只存储字节:A、B、א、ב等等。数据库本身没有“显示”。您的数据库管理UI具有自己的渲染逻辑,Web浏览器也有自己的逻辑,任何其他您可能找到或自己构建的客户端也是如此。数据库本身只有数据。 - Atzmon
我理解你的意思,但是那些数据将会被发送到不同的系统,而这些系统并非由我的团队开发,同时那些文本也需要在他们的系统上以这种方式显示。是强制要求他们都设置视图来支持这种显示更好,还是保存文本的方式,使得不同的系统开发人员不必以特殊的方式处理该文本? - user5326354
1
我会尽可能保持原始数据在数据库中的纯净,并在 UI 层或尽可能靠近它的地方处理显示逻辑。如果您的客户只需要显示此字符串(而不是编辑并将其发送回给您),则可以要求他们应用相同的样式,或者您可以在字符串开头注入一个 Right-to-Left Override (LRO) 控制字符。我会更新我的答案以包括这一点。 - Atzmon
通过在字符串前添加Unicode符号,发送到不同系统的文本将被呈现为问号。这是表示其他系统的编码方式不同吗?如果是,你有什么建议处理方法? - user5326354
有没有支持Windows 1255编码的RLO字符? - user5326354
显示剩余2条评论

3
你可以使用 JavaScript 实现这个功能。
<div id="id_of_content"></div>

<script type="text/javascript">
        // if updating the div in realtime then try using keypress listener to call this function
        function(id_of_content) {
            var text = $('#'+id_of_content).text();
            var words = text.split(' ');
            var result = '';
            for(var j=0;j<words.length;j++) {
                if(/[^a-zA-Z]/.test(words[j])) {
                    var temp = words[j];
                    var rev_word = '';
                    for(var i=0;i<temp.length;i++) {
                        rev_word += temp[temp.length-i-1]
                    }
                result += rev_word;
                }
                else {
                    result += words[j];
                }
            }
        $('#'+id_of_content).text(result);
       }
</script>

希望这可以帮到您。

这段代码不是将整个文本反转了吗?为了实现我的目标,只需要将从左到右的字符反转即可。也就是说,英文字母的组合需要被反转,而希伯来语或阿拉伯语字符应保持不变。 - user5326354
所以我假设输入的句子可能包含英文单词、希伯来语或阿拉伯字符。我已经更新了代码,以反转仅包含字母的单词。 - Sri Kanth
这比那更加复杂。每个单词都可能包含混合的阿拉伯/希伯来语和英文字符。我想我需要在每个单词中找到英文字符的子字符串,然后只翻转该部分单词。这是困难的事情。 - user5326354

2

我正在阅读一些有关RTL的博客和示例,并提供以下可工作示例。

在此代码中,有切换选项,您可以在单击此按钮时尝试LTR和RTL - enter image description here

JSfiddle: http://jsfiddle.net/vikash2402/ammajhy3/3/

以下是其工作代码。

// Jquery, BS3 & Awesome
$('#rtl-button').click(

function () {
    var src = 'http://cdnjs.cloudflare.com/ajax/libs/bootstrap-rtl/3.2.0-rc2/css/bootstrap-rtl.min.css';
    if ($(this).attr('data-direction') == 'ltr') {
        $('head').append('<link href=' + src + ' rel="stylesheet" id="bootstrap-rtl" />');
        $(this).attr('data-direction', 'rtl');
    } else { // by default we load bootstrap-rtl 
        $('head link[href="' + src + '"]').remove();
        $(this).attr('data-direction', 'ltr');
    }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<link href="http://cdnjs.cloudflare.com/ajax/libs/bootstrap-rtl/3.2.0-rc2/css/bootstrap-rtl.min.css" rel="stylesheet"/>
<link href="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet"/>
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/js/bootstrap.min.js"></script>


<div class="container">
    <h3>Testing bootstrap RTL css overwrite</h3>
<nav class="navbar navbar-default" role="navigation">
    <div class="container-fluid">
        <!-- Brand and toggle get grouped for better mobile display -->
        <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1"> <span class="sr-only">Toggle navigation</span>
 <span class="icon-bar"></span>
 <span class="icon-bar"></span>
 <span class="icon-bar"></span>

            </button> <a class="navbar-brand" href="#"><span class="glyphicon glyphicon-home"></span> Home</a>

        </div>
        <!-- Collect the nav links, forms, and other content for toggling -->
        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
            <ul class="nav navbar-nav">
                <li><a href="#">Welcome</a></li>
                <li><a href="#"><span class="glyphicon glyphicon-phone-alt"></span> Contact us</a></li>
                <li><a href="#">Career</a></li>
            </ul>
            <ul class="nav navbar-nav navbar-right">
                <li>
                    <form class="navbar-form" role="search">
                        <div class="form-group">
                            <input type="text" class="form-control" placeholder="Search" />
                        </div>
                        <button type="submit" class="btn btn-default">Submit</button>
                    </form>
                </li>
            </ul>
        </div>
        <!-- /.navbar-collapse -->
    </div>
    <!-- /.container-fluid -->
</nav>
</div>
<a href="#" class="btn btn-default" title="" id="rtl-button" data-direction="ltr"><span class="glyphicon glyphicon-indent-right"></span> RTL</a>

希望这能帮到你:)

2
您可以使用此函数。

function reverseLTR(text) {
    var ltrChars = 'A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02B8\u0300-\u0590\u0800-\u1FFF' + '\u2C00-\uFB1C\uFDFE-\uFE6F\uFEFD-\uFFFF';
    var r = new RegExp("[" + ltrChars + "]?", 'g');
    var ltrMatches = text.match(r);
    var arr = [];
    var insertPlace=0;
    for (var i = 0; i < text.length; i++) {
        if (!ltrMatches[i].length) {//its rtl character
            arr.splice(i, 0, text[i]);
            insertPlace=i+1;
        }
        else arr.splice(insertPlace, 0, text[i]);
    }
    return arr.join("");
}
var text="ABאבCDY";
document.body.innerHTML=text+" converted to : "+reverseLTR(text);


1
尝试使用 <bdo> 标签。
<p>left-to-right.</p>

结果:从左到右。
<p><bdo dir="rtl">right-to-left.</bdo></p>

结果:.tfel-ot-thgir

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接