如何获得文本区域中的光标位置?


75

我有一个textarea,我想知道我是用JavaScript还是光标在textarea的最后一行还是textarea的第一行。

我想到先获取第一个换行符和最后一个换行符的位置,然后再获取光标的位置。

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解决方案。


您在这里看到解决方案了吗?blog.vishalon.net/index.php/…–
John Keyes

这将引发错误,因为indexOflast函数和lastIndexOf函数不是val函数的方法。您应该使用此代码(尽管您根本不应该使用该代码):var firstNewline = String($("#myTextarea").val()).indexOf('\n');
Yaakov Ainspan 2016年

3
光标是鼠标指针,插入符号是其中文本控制器存在指示器。
约翰

@John感谢您的描述。更进一步,从概念上讲,插入号表示文本中的位置,而光标表示任何内容中的位置。关于图形界面,它们具有不同的用途,并且通常具有不同的物理渲染。
Suncat2000 '20

Answers:


92

如果没有选择,则可以使用属性.selectionStart.selectionEnd(没有选择,它们是相等的)。

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

请注意,较旧的浏览器(最著名的是IE8-)不支持此功能。在那里,您必须使用文本范围,但这是一个完全的挫败感。

我相信,尽管有一个库专门用于获取和设置输入元素中的选择/光标位置。我不记得它的名字了,但是关于这个主题的文章似乎很多。


ang 有没有办法让它在IE8中正常工作?谢谢您的解决方案。
Chev

@Alex Ford:我现在看到它实际上已经被回答了:stackoverflow.com/questions/2897155/…
pimvdb 2011年

你是对的。我使用了一个回答者针对您链接的问题提供的jquery插件。做到了。对不起,重复。
Chev

链接的答案在IE <9中无法正常使用换行符。请参阅我的答案。
蒂姆·唐

我认为您在谈论的是jQuery插入符库
mlwacosmos 2014年

23

这是我标准库中的跨浏览器功能:

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?我注意到$符号的
Andi

不。我确实发布了使用jQuery来获取元素引用的示例用法,但是您可以在不使用jQuery的情况下获取元素引用。
gilly3

1

这是获取行号和列位置的代码

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;
}

tArea是文本区域DOM元素

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.