使用JavaScript检测选择文本的结束位置

6
我编写了一段javascript代码来检测选择结束的位置,并在该位置放置一个标记。请参见此jsfiddle:http://jsfiddle.net/vCwwN/ 上述代码执行以下操作:
- 它正确处理所有LTR脚本(例如英语)(正确显示结尾处的标记)。 - 对于LTR脚本(例如英语),它正确处理选择是向前(从左/顶部到右/底部)还是向后(从右/底部到左/顶部),并在选择停止的地方(使用鼠标或键盘)正确显示标记。 - 它使用getClientRects查找所有选择矩形边界,并使用一个hack来检测选择的方向(是否向后)。根据这两个信息,它将标记放在末尾。
您可以尝试选择上述英文脚本而没有任何问题。唯一的问题是当您尝试处理RTL脚本(例如阿拉伯语)时,标记会显示在所选RTL脚本的开头而不是结尾(鼠标/键盘实际停止的地方)。这会引起问题:
- 在RTL脚本(阿拉伯语)内开始选择,并在RTL脚本内结束选择。这会在选择的开头显示标记。 - 在LTR脚本(英语)内开始选择,并在RTL(阿拉伯语)脚本内结束选择。这会在RTL脚本选择的开头显示标记(而不是结尾)。
基本上,从任何地方开始选择(LTR或RTL),并在RTL脚本中结束是不正确的。其他情况都已正确处理(例如以LTR或RTL开头并以LTR结尾,甚至在途中经过RTL脚本)。
问题在于RTL脚本的流向被翻转,因此向后变为向前,向前变为向后。这就是为什么我的代码无法正确处理RTL,并且向后的hack被翻转的原因。
我想到的一个解决方案是检测选择的最后一个字符,看它是否具有RTL脚本,然后根据此翻转向后的标志。我已经放置了一个函数来检测文本是否以RTL字符结尾(它在相同的未使用的jsfiddle中)。它可能会帮助您帮助我解决这个问题 :)

输入元素对我来说不像RTL输入那样运作。dir=rtl缺失了吗? - Halcyon
不,它应该保持原样(即LTR,默认设置)。如果您设置dir = rtl,则两个(RTL / LTR)脚本的整个内容都会翻转。我在自己的代码中处理了(dir = rtl),但决定删除此额外的情况以使代码更简单,并增加获得答案的机会。 - tria
1个回答

0

看看这是否是朝着正确方向迈出的一步。

它利用了Tim Down发布的从用户选择返回HTML代码:

function getSelectionHtml() {
    var html = "";
    if (typeof window.getSelection != "undefined") {
        var sel = window.getSelection();
        if (sel.rangeCount) {
            var container = document.createElement("div");
            for (var i = 0, len = sel.rangeCount; i < len; ++i) {
                container.appendChild(sel.getRangeAt(i).cloneContents());
            }
            html = container.innerHTML;
        }
    } else if (typeof document.selection != "undefined") {
        if (document.selection.type == "Text") {
            html = document.selection.createRange().htmlText;
        }
    }
    return html;
}

一旦定义了这个方法,您就可以调用您定义的lastCharTRL方法来检查最后一个字符是否为RTL并相应地采取行动。
if (lastCharRTL(getSelectionHtml()))
    $('#pointer').css({top: rects[n].top + 10, left: rects[n].left - 10}).show();
else if(backwards)
    $('#pointer').css({top: rects[0].top + 10, left: rects[0].left - 10}).show();
else
    $('#pointer').css({top: rects[n].top + 10, left: rects[n].right}).show();

演示


虽然您的解决方案/演示仍存在原始问题(RTL端选择仍然反转),可能是由于innerHTML和if / else-if / else,但我认为我已经理解了获取选择文本的方法。我知道使用getSelection可以调用toString并获得文本。然后检查开头或结尾(取决于选择的方向)是否有RTL字符。我会尝试这样做并查看结果。谢谢。 - tria

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