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.


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.


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/


@ 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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.