javascript - una - ¿Cómo obtener la posición de intercalación en un área de texto, en caracteres, desde el principio?
eliminar ultimo caracter javascript (4)
¿Cómo se obtiene la posición de intercalación en un <textarea>
usando JavaScript?
Por ejemplo: This is| a text
This is| a text
Esto debería devolver 7
.
¿Cómo conseguirías devolver las cadenas que rodean el cursor / selección?
Ejemplo: ''This is'', '''', '' a text''
.
Si la palabra "es" está resaltada, devolverá ''This '', ''is'', '' a text''
.
Con Firefox, Safari (y otros navegadores basados en Gecko) puede usar fácilmente textarea.selectionStart, pero para IE eso no funciona, por lo que tendrá que hacer algo como esto:
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;
}
También te recomiendo que compruebes el jQuery FieldSelection Plugin, te permite hacer eso y mucho más ...
Editar: De hecho, reimplanté el código anterior:
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;
}
Vea un ejemplo here .
Modifiqué la función anterior para dar cuenta de los retornos de carro en IE. No está probado, pero hice algo similar con él en mi código, por lo que debería ser 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 no tiene que admitir IE, puede usar los atributos selectionStart
y selectionEnd
de textarea
.
Para obtener la posición de cursor, simplemente usa selectionStart
:
function getCaretPosition(textarea) {
return textarea.selectionStart
}
Para obtener las cadenas que rodean la selección, use el siguiente código:
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)]
}
Consulte también developer.mozilla.org/en-US/docs/Web/API/HTMLTextAreaElement .
Actualizado el 5 de septiembre de 2010
Viendo que todo el mundo parece haber sido dirigido aquí para este problema, estoy agregando mi respuesta a una pregunta similar, que contiene el mismo código que esta respuesta, pero con los antecedentes completos para aquellos que estén interesados:
El document.selection.createRange de IE no incluye líneas en blanco iniciales o finales
Para explicar los saltos de línea finales es complicado en IE, y no he visto ninguna solución que lo haga correctamente, incluidas otras respuestas a esta pregunta. Sin embargo, es posible utilizar la siguiente función, que le devolverá el inicio y el final de la selección (que son los mismos en el caso de una intercalación) dentro de un <textarea>
o texto <input>
.
Tenga en cuenta que el área de texto debe tener foco para que esta función funcione correctamente en IE. En caso de duda, primero llame al método focus()
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
};
}