Comment obtenir la position de la colonne caret (pas les pixels) dans une zone de texte, en caractères, depuis le début?
-
06-07-2019 - |
Question
Comment obtenez-vous la position du curseur dans une <textarea>
utilisation de JavaScript?
Par exemple: This is| a text
Ceci devrait renvoyer 7
.
Comment voulez-vous qu'il retourne les chaînes entourant le curseur / la sélection?
Exemple: 'This is', '', ' a text'
.
Si le mot & # 8220; est & # 8221; est mis en surbrillance, il renverra 'This ', 'is', ' a text'
.
La solution
Avec Firefox, Safari (et les autres navigateurs basés sur Gecko), vous pouvez facilement utiliser textarea.selectionStart, mais pour IE, cela ne fonctionne pas. Vous devrez donc faire quelque chose comme ceci:
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 complet ici )
Je vous recommande également de consulter le FieldSelection Plugin de jQuery, ce qui vous permet de le faire et beaucoup plus ...
Modifier: j'ai effectivement réimplémenté le code ci-dessus:
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;
}
Consultez un exemple ici .
Autres conseils
Mis à jour le 5 septembre 2010
Comme tout le monde semble être dirigé ici pour cette question, j'ajoute ma réponse à une question similaire, qui contient le même code que cette réponse, mais avec un arrière-plan complet pour ceux qui sont intéressés:
Document.selection.createRangeRange de IE ne pas inclure de lignes vides de début ou de fin
Il est difficile de prendre en compte les sauts de ligne de fin dans IE, et je n’ai pas vu de solution permettant de le faire correctement, y compris d’autres réponses à cette question. Il est cependant possible d’utiliser la fonction suivante qui vous renverra le début et la fin de la sélection (identiques dans le cas d’un curseur) dans un <textarea>
ou un texte <input>
.
Notez que la zone de texte doit avoir le focus pour que cette fonction fonctionne correctement dans IE. En cas de doute, appelez d’abord la focus()
méthode de la textarea
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
};
}
J'ai modifié la fonction ci-dessus pour prendre en compte les retours à la ligne dans IE. Cela n’a pas été testé, mais j’ai fait quelque chose de similaire avec cela dans mon code, il devrait donc être viable.
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;
}
Si vous n'avez pas besoin de supporter IE, vous pouvez utiliser les attributs selectionStart
et selectionEnd
de textarea
.
Pour obtenir la position du curseur, utilisez simplement <=>:
function getCaretPosition(textarea) {
return textarea.selectionStart
}
Pour obtenir les chaînes entourant la sélection, utilisez le code suivant:
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)]
}
Voir aussi les documents HTMLTextAreaElement .