使用javascript检测选择结束位置 [英] detect selection end position using javascript

查看:128
本文介绍了使用javascript检测选择结束位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编写了一个代码来检测使用javascript的选择结束,并在最终位置放置一个标记。看到这个jsfiddle: http://jsfiddle.net/vCwwN/



上面的代码执行以下操作:


  • 它正确处理所有LTR脚本(例如英语)(正确显示标记)。 li>
  • 对于LTR脚本(例如英语)它可以处理选择是向前(从左/从上到右/下)还是向后(从右/从下到左/上)选择停止(使用鼠标或键盘)。
  • 它使用 getClientRects 来查找所有的选择矩形边界,以及检测到的黑客选择的方向(如果落后或不)。根据这两个信息,它会将标记放在最后。



您可以尝试选择上述英文脚本问题。唯一的问题是,当你尝试处理RTL脚本(例如阿拉伯语)时,那么标记将显示在所选RTL脚本的开头,而不是结尾处(鼠标/键盘实际停止的地方)。这些问题导致:


  • 在RTL脚本(阿拉伯语)中开始选择,并在RTL脚本(阿拉伯语)内结束选择。这将在选择开始时显示标记。 开始在LTR脚本中进行选择(英语),并在RTL(阿拉伯语)脚本内结束选择。这在RTL脚本选择开始时显示标记(而不是结尾)。


    基本上,从任何地方开始选择( LTR或RTL)并以RTL脚本结尾不正确。任何其他情况下都可以正确处理(例如,以LTR或RTL开头,并以LTR结尾,甚至可以通过RTL脚本传递)。

    问题是, RTL脚本会翻转流程,因此向后是向前,向前是向后。这就是为什么我的代码无法正确处理RTL并且逆向破解被逆转。

    我想到的一个解决方案是检测选择的最后一个字符,有或没有RTL脚本,然后基于此翻转后退标志。我已经放置了一个函数来检测文本是否以RTL字符结尾(它与未使用的jsfiddle相同)。它可能会帮助你,帮助我解决它)

    解决方案

    看看这是一个正确的方向。



    它利用以下代码来从用户选择中返回HTML 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。
    }
    }
    返回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

    I wrote a code to detect the end of selection using javascript, and to place a marker at the end position. See this jsfiddle: http://jsfiddle.net/vCwwN/

    The above code do the following:

    • It handles all LTR scripts (e.g. English) properly (showing marker at the end correctly).
    • For LTR scripts (e.g. English) It handles whether the selection is forward (from left/top to right/bottom) or backward (from right/bottom to left/top) properly showing the marker where the selection stopped (using mouse or keyboard).
    • It uses getClientRects to find all the selection rectangles boundaries, and a hack to detect the direction of selection (if backward or not). Depending on these two information, it places the marker at the end.

    You can try selecting what is described above for English script without any problem. The only problem is when you try to handle RTL scripts (e.g. Arabic), then the marker show at the beginning of the selected RTL script rather than the end (where the mouse/keyboard actually stopped). These cause issues:

    • Starting selection inside RTL script (Arabic), and ending selection inside RTL script (Arabic). This show the marker at the start of the selection.
    • Starting selection inside LTR script (English), and ending selection inside RTL (Arabic) script. This show the marker at the start of the RTL script selection (rather than the end of it).

    Basically, selection starting anywhere (LTR or RTL) and ending in RTL script is incorrect. Any other case is correctly handled (e.g. start with LTR or RTL and end with LTR, even passing by RTL scripts on the way).

    The problem is that the direction of flow is flipped for RTL scripts, and therefore backward is forward, and forward is backward. This is why my code cannot handle RTL properly and the backward hack is reversed.

    One solution I thought of is to detect the last character of the selection, and see whether it has RTL script or not, then based on this flip the backward flag. I already placed a function to detect whether a text ends with an RTL character (it is in the same jsfiddle unused). It might help you, help me solve it :)

    解决方案

    See if this is a step in the right direction.

    It leverages the following code to Return HTML from a user selection posted by 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;
    }
    

    Once that is defined, you can call the lastCharTRL method you defined to check whether the last character was RTL and act accordingly.

    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

    这篇关于使用javascript检测选择结束位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆