【问题标题】:How to get the start and end points of selection in text area?如何获取文本区域中选择的起点和终点?
【发布时间】:2011-03-04 11:17:52
【问题描述】:

我想获取文本字段或文本区域中选定范围的光标开始和结束位置。

I tried lot of functions in various forums, but when the last character of the selection is a new line character JavaScript ignore it in IE6.

如何获得选择的起点和终点?

【问题讨论】:

    标签: javascript internet-explorer-6 text-cursor


    【解决方案1】:

    修订后的答案,2010 年 9 月 5 日

    在 IE 中考虑尾随换行符是很棘手的,我还没有看到任何解决方案可以做到这一点。然而,这是可能的。以下是我之前在这里发布的新版本。

    请注意,文本区域必须具有焦点才能使此功能在 IE 中正常工作。如有疑问,请先调用 textarea 的 focus() 方法。

    function getInputSelection(el) {
        var start = 0, end = 0, normalizedValue, range,
            textInputRange, len, endRange;
    
        if (typeof el.selectionStart == "number" && typeof el.selectionEnd == "number") {
            start = el.selectionStart;
            end = el.selectionEnd;
        } else {
            range = document.selection.createRange();
    
            if (range && range.parentElement() == el) {
                len = el.value.length;
                normalizedValue = el.value.replace(/\r\n/g, "\n");
    
                // Create a working TextRange that lives only in the input
                textInputRange = el.createTextRange();
                textInputRange.moveToBookmark(range.getBookmark());
    
                // Check if the start and end of the selection are at the very end
                // of the input, since moveStart/moveEnd doesn't return what we want
                // in those cases
                endRange = el.createTextRange();
                endRange.collapse(false);
    
                if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) {
                    start = end = len;
                } else {
                    start = -textInputRange.moveStart("character", -len);
                    start += normalizedValue.slice(0, start).split("\n").length - 1;
    
                    if (textInputRange.compareEndPoints("EndToEnd", endRange) > -1) {
                        end = len;
                    } else {
                        end = -textInputRange.moveEnd("character", -len);
                        end += normalizedValue.slice(0, end).split("\n").length - 1;
                    }
                }
            }
        }
    
        return {
            start: start,
            end: end
        };
    }
    

    【讨论】:

    • 非常感谢 Tim Down,我已经尝试过这个线程。 but the problem is when the last character of the selection is a new line character JavaScript ignore it in IE.否则这些功能可以正常工作
    • 答案现在完全重写。
    • 非常感谢 Tim Down,这种方法效果很好。用于简单的光标位置。但是如果我们选择一个文本范围来获取所选文本的起始位置。选择的文本自动删除。所以我该如何纠正这个。无论如何,这都是一个不错的技巧,你做了一个 gr8 发明。
    • 是的,这与我发现的问题相同。我现在已经修好了。
    • 噢 gr8 工作正常!!!非常感谢 Tim Down,对我的另一个帮助!!我想在相同的功能中细化选择的终点。我怎样才能实现这个要求。
    【解决方案2】:

    使用 Rangy api,您的所有问题都解决了 gone 没了 没了...

    使用它

    Read the documentation,或者只使用下面的。
    非常简单,

    var selection = rangy.getSelection(),  // Whole lot of information, supports
                                           // multi-selections too.
        start   = selection.anchorOffset,  // Start position
        end     = selection.focusOffset;   // End position
    

    希望这个 api 对您有所帮助,因为它真的有助于处理 跨浏览器 ranges

    【讨论】:

    • Rangy 很棒,但它似乎不适用于文本区域和文本输入。为此,有 rangyinputs(一个 jQuery 插件):code.google.com/p/rangyinputs
    • 嘿,有没有什么方法可以使用 Rangy 而无需安装 node 然后 npm 然后 bower 然后 Rangy?我可以在我的网站中包含一个缩小的 js 文件吗?
    • @EdwardNewell 我相信你可以。尝试使用核心文件here 看看它是否有效。 IIRC 这就是我在将其移至 github 之前使用它的方式。对于其他功能,只需应用不同的模块。
    【解决方案3】:

    我需要做一些非常相似的事情并想出了这个:

    function getSelection(target) {
        var s = {start: 0, end:0};
        if (typeof target.selectionStart == "number"
            && typeof target.selectionEnd == "number") {
            // Firefox (and others)
            s.start = target.selectionStart;
            s.end = target.selectionEnd;
        } else if (document.selection) {
            // IE
            var bookmark = document.selection.createRange().getBookmark();
            var sel = target.createTextRange();
            var bfr = sel.duplicate();
            sel.moveToBookmark(bookmark);
            bfr.setEndPoint("EndToStart", sel);
            s.start = bfr.text.length;
            s.end = s.start + sel.text.length;
        }
        return s;
    }
    

    注意事项:

    • sel 范围必须由 target 而不是使用范围 由document.selection 返回, 否则bfr.setEndPoint 将 抱怨无效的论点。 这个“特征”(发现 在 IE8 中)似乎不是 记录在spec
    • target 必须具有输入焦点才能使此功能起作用。
    • 仅使用 <textarea> 测试过,也可能适用于 <input>

    【讨论】:

    • +1:不是解决方案,而是 sel.moveToBookmark(bookmark);帮了很多忙。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-16
    • 2020-09-30
    • 2022-01-11
    • 1970-01-01
    相关资源
    最近更新 更多