如何在JavaScript中获取文本区域的选定文本范围

How to get range of selected text of textarea in JavaScript

本文关键字:文本 范围 区域 取文本 JavaScript 获取      更新时间:2023-09-26

我正在尝试在文本区域中检索/查找选择的起点和终点。

这是我的代码,在Mozilla和chrome中运行良好,但在InternetExplorer9:中不起作用

<script type="txt/javascript">
    function update(o) {
        var t = o.value, s = getSelectionStart(o), e = getSelectionEnd(o);
        alert("start: " + s + " End: " + e);
    }
    function getSelectionStart(o) {
        if (o.createTextRange) {
            var r = document.selection.createRange().duplicate()
            rse = r.text.length;
            r.moveEnd('character', o.value.length)
            if (r.text == '')
                return o.value.length
            return o.value.lastIndexOf(r.text)
        }
        else
            return o.selectionStart
    }
    function getSelectionEnd(o) {
        if (o.createTextRange) {
            var r = document.selection.createRang;
            e().duplicate()
            r.moveStart('character', -o.value.length)
            return r.text.length
        }
        else
            return o.selectionEnd
    }
</script>
<textarea id ="text" rows=10 cols="50" onselect="update(this);"></textarea>

当我在Mozilla和Chrome中测试这段代码时,它给出了正确的答案,但当我在InternetExplorer9中运行这段代码,它显示-1表示开始,任何值表示结束。

我只想找出文本区域所选文本的起点和终点/索引。实际上,上面的代码适用于所有浏览器中的文本框,但不适用于文本区域。

我该怎么修?

使用下面的代码或检查此fiddle

   function getTextSelection(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;
                }
            }
        }
    }
    alert("start :" + start + " End :" + end);
}

虽然最初的答案可能在2012年帮助了OP,但事情已经发生了变化,这现在变得更简单了,至少在现代浏览器中是这样。


您可以使用文本区域的JavaScript selectionStartselectionEnd属性。

基本用途

这两个标准属性都适用于当今的主要浏览器(Chrome、Safari、Firefox、Opera、Edge和IE)。

例如:

console.log(
    document.getElementById("text").selectionStart,
    document.getElementById("text").selectionEnd
)

将在ID为text的文本区域中显示选择的起点和终点。

边界情况

如果在文本区域中没有选择任何项目,则开始和结束属性都将返回插入符号的最后位置。如果文本区域尚未接收到焦点,则两个属性都将返回值0

更改所选内容

通过将这些属性设置为新值,您将调整活动文本选择。因此,您也可以使用它来选择文本区域中的文本。

检查选择是否到位

您可以通过检查两个值是否不同来检查当前是否有选择,即

document.getElementById("text").selectionStart != document.getElementById("text").selectionEnd

如果是true,则存在文本选择。

Demo

const textarea = document.getElementById("text");
const selStart = document.getElementById("selStart");
const selEnd = document.getElementById("selEnd");
// should maybe also look at other events, e.g. "keydown", "select", etc
textarea.addEventListener("mousemove", () => {
  selStart.innerText = textarea.selectionStart;
  selEnd.innerText = textarea.selectionEnd;
});
<textarea id="text">Some text here</textarea>
<p>Selection Start: <span id="selStart">0</span></p>
<p>Selection End: <span id="selEnd">0</span></p>

参考文献

  • 现场演示(JSFiddle)
  • MDN的文档
  • MSDN上的文档