Wie erhält man die Caret-Position in einem <textarea>
mit JavaScript?
Beispielsweise: This is| a text
Dies sollte 7
.
Wie würden Sie es schaffen, die den Cursor/die Auswahl umgebenden Zeichenfolgen zurückzugeben?
Z.B.: 'This is', '', ' a text'
.
Wenn das Wort "ist" markiert ist, würde es 'This ', 'is', ' a text'
.
Mit Firefox, Safari (und anderen Gecko-basierten Browsern) können Sie textarea.selectionStart problemlos verwenden, aber für IE) funktioniert das nicht, daher müssen Sie Folgendes tun:
function getCaret(node) {
if (node.selectionStart) {
return node.selectionStart;
} else if (!document.selection) {
return 0;
}
var c = "\001",
sel = document.selection.createRange(),
dul = sel.duplicate(),
len = 0;
dul.moveToElementText(node);
sel.text = c;
len = dul.text.indexOf(c);
sel.moveStart('character',-1);
sel.text = "";
return len;
}
( Code hier vervollständigen )
Ich empfehle Ihnen auch, das jQuery FieldSelection Plugin zu überprüfen, damit können Sie das und vieles mehr ...
Edit: Ich habe den obigen Code tatsächlich neu implementiert:
function getCaret(el) {
if (el.selectionStart) {
return el.selectionStart;
} else if (document.selection) {
el.focus();
var r = document.selection.createRange();
if (r == null) {
return 0;
}
var re = el.createTextRange(),
rc = re.duplicate();
re.moveToBookmark(r.getBookmark());
rc.setEndPoint('EndToStart', re);
return rc.text.length;
}
return 0;
}
Überprüfen Sie ein Beispiel hier .
Aktualisiert am 5. September 2010
Da hier offenbar alle auf dieses Problem hingewiesen werden, füge ich meine Antwort einer ähnlichen Frage hinzu, die den gleichen Code wie diese Antwort enthält, aber den vollständigen Hintergrund für alle Interessierten bietet:
IE document.selection.createRange enthält keine führenden oder nachfolgenden Leerzeilen
Die Berücksichtigung nachfolgender Zeilenumbrüche ist im Internet Explorer schwierig, und ich habe keine Lösung gefunden, die dies korrekt ausführt, einschließlich anderer Antworten auf diese Frage. Mit der folgenden Funktion können Sie jedoch den Anfang und das Ende der Auswahl (die bei einem Caret identisch sind) innerhalb eines <textarea>
Oder eines Textes <input>
Zurückgeben. .
Beachten Sie, dass das Textfeld den Fokus haben muss, damit diese Funktion im Internet Explorer ordnungsgemäß funktioniert. Rufen Sie im Zweifelsfall zuerst die Methode focus()
des Textbereichs auf.
function getInputSelection(el) {
var start = 0, end = 0, normalizedValue, range,
textInputRange, len, endRange;
if (typeof el.selectionStart == "number" && typeof el.selectionEnd == "number") {
start = el.selectionStart;
end = el.selectionEnd;
} else {
range = document.selection.createRange();
if (range && range.parentElement() == el) {
len = el.value.length;
normalizedValue = el.value.replace(/\r\n/g, "\n");
// Create a working TextRange that lives only in the input
textInputRange = el.createTextRange();
textInputRange.moveToBookmark(range.getBookmark());
// Check if the start and end of the selection are at the very end
// of the input, since moveStart/moveEnd doesn't return what we want
// in those cases
endRange = el.createTextRange();
endRange.collapse(false);
if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) {
start = end = len;
} else {
start = -textInputRange.moveStart("character", -len);
start += normalizedValue.slice(0, start).split("\n").length - 1;
if (textInputRange.compareEndPoints("EndToEnd", endRange) > -1) {
end = len;
} else {
end = -textInputRange.moveEnd("character", -len);
end += normalizedValue.slice(0, end).split("\n").length - 1;
}
}
}
}
return {
start: start,
end: end
};
}
Ich habe die obige Funktion geändert, um Wagenrückläufe im IE zu berücksichtigen. Es ist ungetestet, aber ich habe etwas Ähnliches damit in meinem Code gemacht, damit es funktionieren sollte.
function getCaret(el) {
if (el.selectionStart) {
return el.selectionStart;
} else if (document.selection) {
el.focus();
var r = document.selection.createRange();
if (r == null) {
return 0;
}
var re = el.createTextRange(),
rc = re.duplicate();
re.moveToBookmark(r.getBookmark());
rc.setEndPoint('EndToStart', re);
var add_newlines = 0;
for (var i=0; i<rc.text.length; i++) {
if (rc.text.substr(i, 2) == '\r\n') {
add_newlines += 2;
i++;
}
}
//return rc.text.length + add_newlines;
//We need to substract the no. of lines
return rc.text.length - add_newlines;
}
return 0;
}
Wenn Sie IE nicht unterstützen müssen, können Sie die selectionStart
- und selectionEnd
-Attribute von textarea
verwenden.
Um die Position des Carets zu ermitteln, verwenden Sie einfach selectionStart
:
function getCaretPosition(textarea) {
return textarea.selectionStart
}
Verwenden Sie folgenden Code, um die die Auswahl umgebenden Zeichenfolgen abzurufen:
function getSurroundingSelection(textarea) {
return [textarea.value.substring(0, textarea.selectionStart)
,textarea.value.substring(textarea.selectionStart, textarea.selectionEnd)
,textarea.value.substring(textarea.selectionEnd, textarea.value.length)]
}
Siehe auch HTMLTextAreaElement docs .