Wie erhält man die Cursorposition in einem Textbereich?

75

Ich habe einen Textbereich und möchte wissen, ob ich mich mit meinem Cursor mit JavaScript in der letzten Zeile des Textbereichs oder in der ersten Zeile des Textbereichs befinde.

Ich dachte daran, die Position des ersten Zeilenumbruchs und des letzten Zeilenumbruchs zu erfassen und dann die Position des Cursors zu ermitteln.

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.
  • Ist es möglich, die Cursorposition innerhalb des Textbereichs zu erfassen?
  • Haben Sie einen besseren Vorschlag, um herauszufinden, ob ich mich in der ersten oder letzten Zeile eines Textbereichs befinde?

jQuery-Lösungen werden bevorzugt, es sei denn, JavaScript ist so einfach oder einfacher.

Chev
quelle
Haben Sie die Lösung hier gesehen: blog.vishalon.net/index.php/…
John Keyes
Dies indexOflöst einen Fehler aus, da die Funktionen und lastIndexOf` keine Methoden der Funktion val` sind. Sie sollten dies verwenden (obwohl Sie diesen Code überhaupt nicht verwenden sollten):var firstNewline = String($("#myTextarea").val()).indexOf('\n');
Yaakov Ainspan
3
Der Cursor ist Ihr Mauszeiger, das Caret ist der Indikator, an dem sich der Textcontroller befindet.
John
@ John Danke für die Beschreibung. Um weiter zu gehen, repräsentiert konzeptionell ein Caret eine Position im Text, während ein Cursor eine Position in irgendetwas repräsentiert. In Bezug auf grafische Oberflächen haben sie unterschiedliche Zwecke und häufig unterschiedliche physische Renderings.
Suncat2000

Antworten:

92

Wenn keine Auswahl vorhanden ist, können Sie die Eigenschaften verwenden .selectionStartoder .selectionEnd(ohne Auswahl sind sie gleich).

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

Beachten Sie, dass dies in älteren Browsern, insbesondere IE8-, nicht unterstützt wird. Dort müssen Sie mit Textbereichen arbeiten, aber es ist eine völlige Frustration.

Ich glaube, es gibt irgendwo eine Bibliothek, die sich dem Abrufen und Setzen von Auswahlen / Cursorpositionen in Eingabeelementen widmet. Ich kann mich nicht an seinen Namen erinnern, aber es scheint Dutzende von Artikeln zu diesem Thema zu geben.

pimvdb
quelle
Dang. Gibt es eine Möglichkeit, dies in IE8 zum Laufen zu bringen? Vielen Dank für die Lösung.
Chev
@ Alex Ford: Ich sehe jetzt, dass es tatsächlich zuvor beantwortet wurde: stackoverflow.com/questions/2897155/… .
Pimvdb
Du hast Recht. Ich habe das JQuery-Plugin verwendet, das ein Antwortender auf die von Ihnen verlinkte Frage gegeben hat. Das hat es geschafft. Entschuldigung für das Duplikat.
Chev
Die verknüpfte Antwort funktioniert bei Zeilenumbrüchen in IE <9 nicht richtig. Siehe meine Antwort.
Tim Down
Ich denke, Sie sprechen über JQuery Caret Library
mlwacosmos
23

Hier ist eine browserübergreifende Funktion, die ich in meiner Standardbibliothek habe:

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

Verwenden Sie es in Ihrem Code wie folgt:

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

Hier ist seine ergänzende Funktion:

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/

gilly3
quelle
@ TimDown - Du hast recht. Mir ist jetzt klar, dass ich die Version, die ich hier eingefügt habe, <input>ausschließlich für Steuerelemente verwendet habe. Ich habe meine Antwort so bearbeitet, dass eine Version verwendet wird, die auch für <textarea>Steuerelemente funktioniert .
Gilly3
Benötigt es JQuery? Ich bemerkte bc des $ Symbols
Andi Hamolli
Nein. Ich habe eine Beispielverwendung veröffentlicht, die jQuery verwendet, um die Elementreferenz abzurufen, aber Sie können die Elementreferenz ohne jQuery abrufen.
gilly3
1

Hier ist der Code zum Abrufen der Zeilennummer und der Spaltenposition

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 ist das DOM-Element des Textbereichs

Clay Smith
quelle