使用javascript检测选择结束位置

时间:2013-03-07 17:01:34

标签: javascript html selection right-to-left

我编写了一个代码,用于使用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并且后向黑客被逆转的原因。

我想到的一个解决方案是检测选择的最后一个字符,看看它是否有RTL脚本,然后根据这个翻转后向标志。我已经放置了一个函数来检测文本是否以RTL字符结尾(它与未使用的jsfiddle相同)。它可能对你有所帮助,帮助我解决它:)

1 个答案:

答案 0 :(得分:0)

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

它利用以下代码Return HTML from a user selection发布的Tim Down

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();

<强> DEMO