Voici une paire de fonctions qui obtiennent et définissent la position de sélection/caret dans une zone de texte dans tous les principaux navigateurs.
Remarque: si vous n'avez pas besoin de soutenir IE < = 8, il suffit d'utiliser les selectionStart
et selectionEnd
propriétés (MDN). Tout le code compliqué ci-dessous est juste là pour soutenir les anciennes versions de IE.
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
};
}
function offsetToRangeCharacterMove(el, offset) {
return offset - (el.value.slice(0, offset).split("\r\n").length - 1);
}
function setInputSelection(el, startOffset, endOffset) {
if (typeof el.selectionStart == "number" && typeof el.selectionEnd == "number") {
el.selectionStart = startOffset;
el.selectionEnd = endOffset;
} else {
var range = el.createTextRange();
var startCharMove = offsetToRangeCharacterMove(el, startOffset);
range.collapse(true);
if (startOffset == endOffset) {
range.move("character", startCharMove);
} else {
range.moveEnd("character", offsetToRangeCharacterMove(el, endOffset));
range.moveStart("character", startCharMove);
}
range.select();
}
}
Lorsque vous modifiez la valeur de la zone de texte, enregistrez d'abord la sélection, puis la restaurer après:
var t = document.getElementById("textarea");
var sel = getInputSelection(t);
t.value = some_new_value;
setInputSelection(t, sel.start, sel.end);
Est-ce que le travail de la fonction 'setInputSelection' que dans IE? Je demande parce que la méthode 'createTextRange' n'existe pas (pour les éléments d'entrée) dans les autres navigateurs, de sorte qu'une erreur est levée. –
@ Šime: Oh, oui, désolé. Copier/coller d'une question d'IE seulement Réviser maintenant ... –
@ Šime: ... et fini. –