Як отримати позицію курсора в текстовій області?


75

У мене є текстове поле, і я хотів би знати, чи перебуваю я в останньому рядку текстового поля або в першому рядку текстового поля за допомогою курсора з 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 не є таким простим або простим.


Ви бачили рішення тут: blog.vishalon.net/index.php/…
Джон Кіз,

Це призведе до помилки, оскільки функції indexOfі lastIndexOf` не є методами функції val`. Вам слід використовувати це (хоча ви не повинні використовувати цей код взагалі):var firstNewline = String($("#myTextarea").val()).indexOf('\n');
Yaakov Ainspan

3
Курсор знаходиться покажчик миші, то каретка є індикатором , де текст контролера присутній.
Джон

@ John Спасибі за опис. Щоб піти далі, концептуально каретка представляє місце в тексті, а курсор - місце в чому-небудь. Що стосується графічних інтерфейсів, вони мають різні цілі та, часто, різні фізичні візуалізації.
Suncat2000

Відповіді:


92

Якщо виділення немає, ви можете використовувати властивості .selectionStartабо .selectionEnd(без виділення вони рівні).

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

Зверніть увагу, що це не підтримується у старих браузерах, особливо у IE8-. Там вам доведеться працювати з діапазонами тексту, але це повне розчарування.

Я вважаю, що десь є бібліотека, яка присвячена отриманню та встановленню вибору / позицій курсору в елементах введення. Я не можу згадати його назви, але, здається, у статтях на цю тему є десятки.


Денг. Чи є спосіб змусити це працювати в IE8? Дякую за рішення.
Chev

@ Алекс Форд: Зараз я бачу, що на нього вже відповідали раніше: stackoverflow.com/questions/2897155/… .
pimvdb

Ви праві. Я використав плагін jquery, який один відповідач дав на питання, яке ви зв’язали. Це вдалося. Вибачте за дублікат.
Chev

Відповідна відповідь не працює належним чином із розривами рядків в IE <9. Перегляньте мою відповідь.
Тім Даун

Думаю, ви говорите про бібліотеку jquery
caret

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? Я помітив bc символу $
Анді

Ні. Я публікував приклад використання, яке використовує 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 текстової області

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.