如何在文本区域中获取光标位置?

92
我有一个文本域,我想知道在使用JavaScript时我的光标是否在文本域的最后一行或第一行。
我考虑获取第一个换行符和最后一个换行符的位置,然后再获取光标所在的位置。
var firstNewline = $('#myTextarea').val().indexOf('\n');
var lastNewline = $('#myTextarea').val().lastIndexOf('\n');

var cursorPosition = ?????;

if (cursorPosition < firstNewline)
    // I am on first line.
else if (cursorPosition > lastNewline)
    // I am on last line.
  • 是否可以获取文本区域内的光标位置?
  • 你有更好的方法来确定我是否在文本区域的第一行或者最后一行吗?

如果JavaScript简单或更简单,优先考虑使用jQuery解决方案。


你看过这里的解决方案了吗:http://blog.vishalon.net/index.php/javascript-getting-and-setting-caret-position-in-textarea/ - John Keyes
这会抛出一个错误,因为indexOflastIndexOf函数不是val函数的方法。你应该使用这个(尽管你根本不应该使用那段代码):var firstNewline = String($("#myTextarea").val()).indexOf('\n'); - yaakov
4
光标指的是你的鼠标指针,而插入符号则是文本控制器所在位置的指示器。 - John
1
@John 感谢您的描述。从概念上讲,插入符号代表文本中的位置,而光标代表任何东西中的位置。关于图形界面,它们有着不同的目的,并且通常具有不同的物理呈现方式。 - Suncat2000
3个回答

119

如果没有选取任何内容,你可以使用.selectionStart或者.selectionEnd属性(在没有选取内容的情况下它们相等)。

var cursorPosition = $('#myTextarea').prop("selectionStart");

请注意,这在旧版浏览器中不受支持,尤其是IE8及以下版本。在那种情况下,您必须使用文本范围进行操作,但这非常令人沮丧。

我相信有一个专门用于获取和设置输入元素中选择/光标位置的库。我无法记住它的名称,但似乎有许多关于这个主题的文章。


当。是否有办法让它在IE8上运行?感谢您的解决方案。 - Chev
@Alex Ford:我现在看到事实上已经有人回答过了:https://dev59.com/onE85IYBdhLWcg3wMQhm。 - pimvdb
你说得对。我使用了那个回答者在你提供的问题中给出的jQuery插件。这就解决了问题。抱歉造成重复。 - Chev
链接的答案在IE < 9中无法正确处理换行符。请查看我的答案。 - Tim Down
我认为你在谈论jQuery插件caret库。 - mlwacosmos
我得到了未定义 - Nathan B

34

这是我标准库中的一个跨浏览器函数:

function getCursorPos(input) {
    if ("selectionStart" in input && document.activeElement == input) {
        return {
            start: input.selectionStart,
            end: input.selectionEnd
        };
    }
    else if (input.createTextRange) {
        var sel = document.selection.createRange();
        if (sel.parentElement() === input) {
            var rng = input.createTextRange();
            rng.moveToBookmark(sel.getBookmark());
            for (var len = 0;
                     rng.compareEndPoints("EndToStart", rng) > 0;
                     rng.moveEnd("character", -1)) {
                len++;
            }
            rng.setEndPoint("StartToStart", input.createTextRange());
            for (var pos = { start: 0, end: len };
                     rng.compareEndPoints("EndToStart", rng) > 0;
                     rng.moveEnd("character", -1)) {
                pos.start++;
                pos.end++;
            }
            return pos;
        }
    }
    return -1;
}

像这样在您的代码中使用它:

var cursorPosition = getCursorPos($('#myTextarea')[0])

这是它的互补函数:

function setCursorPos(input, start, end) {
    if (arguments.length < 3) end = start;
    if ("selectionStart" in input) {
        setTimeout(function() {
            input.selectionStart = start;
            input.selectionEnd = end;
        }, 1);
    }
    else if (input.createTextRange) {
        var rng = input.createTextRange();
        rng.moveStart("character", start);
        rng.collapse();
        rng.moveEnd("character", end - start);
        rng.select();
    }
}

http://jsfiddle.net/gilly3/6SUN8/


@TimDown - 你说得对。我现在意识到,我在这里粘贴的版本,我一直在专门使用<input>控件。我已经编辑了我的答案,使用一个同样适用于<textarea>控件的版本。 - gilly3
需要使用jQuery吗?我注意到了$符号。 - user5730329
不,我确实发布了一个使用jQuery获取元素引用的示例用法,但是你可以在没有jQuery的情况下获取元素引用。 - gilly3

4
这里是获取行号和列位置的代码。
function getLineNumber(tArea) {

    return tArea.value.substr(0, tArea.selectionStart).split("\n").length;
}

function getCursorPos() {
    var me = $("textarea[name='documenttext']")[0];
    var el = $(me).get(0);
    var pos = 0;
    if ('selectionStart' in el) {
        pos = el.selectionStart;
    } else if ('selection' in document) {
        el.focus();
        var Sel = document.selection.createRange();
        var SelLength = document.selection.createRange().text.length;
        Sel.moveStart('character', -el.value.length);
        pos = Sel.text.length - SelLength;
    }
    var ret = pos - prevLine(me);
    alert(ret);

    return ret; 
}

function prevLine(me) {
    var lineArr = me.value.substr(0, me.selectionStart).split("\n");

    var numChars = 0;

    for (var i = 0; i < lineArr.length-1; i++) {
        numChars += lineArr[i].length+1;
    }

    return numChars;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接