Как получить позицию курсора в текстовом поле?

У меня есть текстовое поле, и я хотел бы знать, нахожусь ли я на последней строке текстового поля или на первой строке текстового поля с моим курсором с помощью 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.
  • Можно ли захватить позицию курсора в текстовом поле?
  • У вас есть лучшее предложение, чтобы узнать, нахожусь ли я в первой или последней строке текстового поля?

Решения jQuery предпочтительнее, если JavaScript не настолько прост или проще.


person Chev    schedule 12.10.2011    source источник
comment
Вы видели здесь решение: blog.vishalon.net/index.php/   -  person John Keyes    schedule 13.10.2011
comment
Это вызовет ошибку, поскольку функции indexOf и lastIndexOf` не являются методами функции val. Вы должны использовать это (хотя вам вообще не следует использовать этот код): var firstNewline = String($("#myTextarea").val()).indexOf('\n');   -  person Yaakov Ainspan    schedule 11.01.2016
comment
Курсор - это указатель мыши, курсор - это индикатор, в котором находится текстовый контроллер.   -  person John    schedule 29.05.2018
comment
@John Спасибо за описание. Чтобы пойти дальше, концептуально курсор представляет собой место в тексте, а курсор - это место в любом месте. Что касается графических интерфейсов, то они имеют разные цели и, зачастую, разную физическую визуализацию.   -  person Suncat2000    schedule 21.04.2020


Ответы (3)


Если нет выбора, вы можете использовать свойства .selectionStart или .selectionEnd (без выбора они равны).

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

Обратите внимание, что это не поддерживается в старых браузерах, особенно в IE8-. Там с текстовыми диапазонами придется поработать, но это полное разочарование.

Я считаю, что где-то есть библиотека, которая предназначена для получения и установки выделений / позиций курсора в элементах ввода. Не могу вспомнить его название, но статей на эту тему вроде бы десятки.

person pimvdb    schedule 12.10.2011
comment
Черт возьми. Есть ли способ заставить это работать в IE8? Спасибо за решение. - person Chev; 13.10.2011
comment
@Alex Ford: теперь я вижу, что на него уже был дан ответ: stackoverflow.com/questions/2897155/. - person pimvdb; 13.10.2011
comment
Ты прав. Я использовал плагин jquery, который один ответчик дал на вопрос, который вы связали. Это сделало это. Извините за дубликат. - person Chev; 13.10.2011
comment
Связанный ответ не работает должным образом с разрывами строки в IE ‹9. См. Мой ответ. - person Tim Down; 13.10.2011
comment
Я думаю, вы говорите о библиотеке jQuery Caret - person mlwacosmos; 07.11.2014
comment
Я не могу определить - person Nathan B; 07.05.2018

Вот кроссбраузерная функция, которая есть в моей стандартной библиотеке:

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/

person gilly3    schedule 12.10.2011
comment
@TimDown - Вы правы. Теперь я понимаю, что версию, которую я вставил сюда, я использовал исключительно для <input> элементов управления. Я отредактировал свой ответ, чтобы использовать версию, которая также работает для <textarea> элементов управления. - person gilly3; 23.05.2012
comment
Требуется ли JQuery? Я заметил bc символа $ - person Andi; 10.07.2017
comment
Нет. Я опубликовал пример использования jQuery для получения ссылки на элемент, но вы можете получить ссылку на элемент без jQuery. - person gilly3; 10.07.2017

Вот код для получения номера строки и позиции столбца

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 текстовой области

person Clay Smith    schedule 04.08.2015