个性化阅读
专注于IT技术分析

如何在JavaScript的文本输入或文本区域中获取当前光标位置(和选择)

本文概述

在文本区域内检索光标(尖号)的位置比你想象的要容易。尽管你不会获得名为” cursorPosition”或” caretPosition”的属性, 但是你可以从与元素基本相同的selectionStart属性中减去该值。这些值(开始和结束)始终提供一个整数值, 其中包含文本区域或文本输入中所选文本的索引。如果未选择任何文本, 则这些值(开始和结束)将相同, 这意味着它们等于光标在元素中的位置。

典型方式

每个文本区域和文本输入都应该具有selectionStart和selectionEnd属性, 它们分别包含选择的开始位置的字符索引和选择的结束位置的字符索引。

<input type="text" id="text-element" />
<!-- Or a textarea
<textarea id="text-element"></textarea>
-->
<input type="button" id="trigger" value="Check"/>

<script>
    document.getElementById("trigger").addEventListener("click", function(){
        var myElement = document.getElementById('text-element');
        var startPosition = myElement.selectionStart;
        var endPosition = myElement.selectionEnd;
        
        // Check if you've selected text
        if(startPosition == endPosition){
            alert("The position of the cursor is (" + startPosition + "/" + myElement.value.length + ")");
        }else{
            alert("Selected text from ("+ startPosition +" to "+ endPosition + " of " + myElement.value.length + ")");
        }
    }, false);
</script>

该方法将独立于每种现代浏览器上的元素类型(输入文本或文本区域)工作。

IE <8支持

遗憾的是, Internet Explorer浏览器<8不提供对selectionStart和selectionEnd属性的支持, 因此我们需要使用文本范围来解决此问题, 而又不会严重影响性能。

为了提供对旧浏览器的支持, 请使用以下方法。该方法是异步的, 它期望第一个参数是DOM元素(无论是文本区域还是文本输入), 并且它将返回具有2个属性的对象(开始和结束与selectionStart和selectionEnd的值相等)。

/**
 * Return an object with the selection range or cursor position (if both have the same value)
 * @param {DOMElement} el A dom element of a textarea or input text.
 * @return {Object} reference Object with 2 properties (start and end) with the identifier of the location of the cursor and selected text.
 **/
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
    };
}

你可以使用上一个功能轻松使用它(请记住使用focus方法对输入进行聚焦以防止出现任何错误):

var element = document.getElementById("someID");
// Focus element, in case that it's not
element.focus();
var result = getInputSelection(element);

console.log(result);
// {
//   start: 5, //   end: 5
// }

并在下面的小提琴中查看一个实时示例:

上一个代码段已发布在StackOverflow中, 而回答的代码段创建了一个具有MIT许可证的存储库。迷你库是jQuery的包装器, 用于完成与文本输入和文本输入或textarea元素(getSelection, setSelection, deleteText等)中的文本选择和位置有关的常规任务。

结论

  • 如果开始和结束值相同, 则表示没有选定的文本, 并且开始值(或结束值)是光标的位置。
  • 请注意, 在IE中, 在调用上述方法之前, textarea或文本输入必须具有焦点。你可以通过调用元素(或其jQuery对象)的focus()方法来确保这一点。

玩得开心 !

赞(0)
未经允许不得转载:srcmini » 如何在JavaScript的文本输入或文本区域中获取当前光标位置(和选择)

评论 抢沙发

评论前必须登录!