¿Cuál es la mejor manera (y supongo que es la más simple) para colocar el cursor al final del texto en un elemento de texto de entrada a través de JavaScript, después de que se haya establecido el foco en el elemento?
fuente
¿Cuál es la mejor manera (y supongo que es la más simple) para colocar el cursor al final del texto en un elemento de texto de entrada a través de JavaScript, después de que se haya establecido el foco en el elemento?
Me enfrenté a este mismo problema (después de establecer el enfoque a través de RJS / prototipo) en IE. Firefox ya estaba dejando el cursor al final cuando ya hay un valor para el campo. IE estaba forzando el cursor al comienzo del texto.
La solución a la que llegué es la siguiente:
<input id="search" type="text" value="mycurrtext" size="30"
onfocus="this.value = this.value;" name="search"/>
Esto funciona tanto en IE7 como en FF3
Hay una manera simple de hacerlo funcionar en la mayoría de los navegadores.
this.selectionStart = this.selectionEnd = this.value.length;
Sin embargo, debido a las peculiaridades * de algunos navegadores, una respuesta más inclusiva se parece más a esto
setTimeout(function(){ that.selectionStart = that.selectionEnd = 10000; }, 0);
Usando jQuery (para configurar el oyente, pero de lo contrario no es necesario)
Usando Vanilla JS ( addEvent
función de préstamo de esta respuesta )
Chrome tiene una peculiaridad extraña donde el evento de foco se dispara antes de que el cursor se mueva al campo; que arruina mi solución simple. Dos opciones para arreglar esto:
focus
a mouseup
. Esto sería bastante molesto para el usuario a menos que aún mantuvieras un seguimiento del enfoque. No estoy realmente enamorado de ninguna de estas opciones.Además, @vladkras señaló que algunas versiones anteriores de Opera calculan incorrectamente la longitud cuando tiene espacios. Para esto, puede usar un número enorme que debería ser más grande que su cadena.
this.selectionStart = this.selectionEnd = 0;
Esto debería mover el foco antes de la primera letra del cuadro de entrada. Pero más bien, cuando depuré, ¡ni siquiera está cambiando el valor de selectionEnd y selectionStart! ¡Y tampoco lo mueves al primer personaje!
selectionStart
y length
devolvía un número menor en los espacios. Es por eso que uso 10000
o cualquier otro número lo suficientemente grande en lugar de this.value.length
(probado en IE8 e IE11)
Prueba esto, me ha funcionado:
//input is the input element
input.focus(); //sets focus to element
var val = this.input.value; //store the value of the element
this.input.value = ''; //clear the value of the element
this.input.value = val; //set that value back.
Para que el cursor se mueva hasta el final, la entrada debe tener el foco primero, luego, cuando se cambia el valor, irá al final. Si establece .value en el mismo, no cambiará en Chrome.
this.
delante de la entrada en las líneas 2, 3 y 4? Ya sabemos que ese input
es el elemento de entrada. Usar this
parece redundante. Buena solución de lo contrario!
$input.focus().val($input.val());
Después de hackear esto un poco, encontré que la mejor manera era usar el setSelectionRange
función si el navegador lo admite; si no, vuelva a usar el método en la respuesta de Mike Berrow (es decir, reemplace el valor por sí mismo).
También estoy configurando scrollTop
un valor alto en caso de que estemos en un desplazamiento vertical textarea
. (Usar un valor alto arbitrario parece más confiable que $(this).height()
en Firefox y Chrome).
Lo hice como un complemento jQuery. (Si no está utilizando jQuery, confío en que aún puede obtener la esencia lo suficientemente fácil).
He probado en IE6, IE7, IE8, Firefox 3.5.5, Google Chrome 3.0, Safari 4.0.4, Opera 10.00.
Está disponible en jquery.com como el complemento PutCursorAtEnd . Para su comodidad, el código para la versión 1.0 es el siguiente:
// jQuery plugin: PutCursorAtEnd 1.0
// http://plugins.jquery.com/project/PutCursorAtEnd
// by teedyay
//
// Puts the cursor at the end of a textbox/ textarea
// codesnippet: 691e18b1-f4f9-41b4-8fe8-bc8ee51b48d4
(function($)
{
jQuery.fn.putCursorAtEnd = function()
{
return this.each(function()
{
$(this).focus()
// If this function exists...
if (this.setSelectionRange)
{
// ... then use it
// (Doesn't work in IE)
// Double the length because Opera is inconsistent about whether a carriage return is one character or two. Sigh.
var len = $(this).val().length * 2;
this.setSelectionRange(len, len);
}
else
{
// ... otherwise replace the contents with itself
// (Doesn't work in Google Chrome)
$(this).val($(this).val());
}
// Scroll to the bottom, in case we're in a tall textarea
// (Necessary for Firefox and Google Chrome)
this.scrollTop = 999999;
});
};
})(jQuery);
<script type="text/javascript">
function SetEnd(txt) {
if (txt.createTextRange) {
//IE
var FieldRange = txt.createTextRange();
FieldRange.moveStart('character', txt.value.length);
FieldRange.collapse();
FieldRange.select();
}
else {
//Firefox and Opera
txt.focus();
var length = txt.value.length;
txt.setSelectionRange(length, length);
}
}
</script>
Esta función me funciona en IE9, Firefox 6.xy Opera 11.x
SCRIPT16389: Unspecified error.
He intentado lo siguiente con bastante éxito en Chrome
$("input.focus").focus(function () {
var val = this.value,
$this = $(this);
$this.val("");
setTimeout(function () {
$this.val(val);
}, 1);
});
Resumen rápido:
Toma cada campo de entrada con el foco de la clase en él, luego almacena el valor anterior del campo de entrada en una variable, luego aplica la cadena vacía al campo de entrada.
Luego espera 1 milisegundo y vuelve a poner el valor anterior.
Es 2019 y ninguno de los métodos anteriores funcionó para mí, pero este lo hizo, tomado de https://css-tricks.com/snippets/javascript/move-cursor-to-end-of-input/
function moveCursorToEnd(id) {
var el = document.getElementById(id)
el.focus()
if (typeof el.selectionStart == "number") {
el.selectionStart = el.selectionEnd = el.value.length;
} else if (typeof el.createTextRange != "undefined") {
var range = el.createTextRange();
range.collapse(false);
range.select();
}
}
<input id="myinput" type="text" />
<a href="#" onclick="moveCursorToEnd('myinput')">Move cursor to end</a>
el.focus()
en el, else if
así que no funcionó en algunos casos. Verifiqué que esto funciona ahora en Chrome y (estremecimiento) IE
Sencillo. Al editar o cambiar valores, primero ponga el foco y luego ajuste el valor.
$("#catg_name").focus();
$("#catg_name").val(catg_name);
Todavía se necesita la variable intermedia, (ver var val =) de lo contrario el cursor se comporta de manera extraña, lo necesitamos al final.
<body onload="document.getElementById('userinput').focus();">
<form>
<input id="userinput" onfocus="var val=this.value; this.value=''; this.value= val;"
class=large type="text" size="10" maxlength="50" value="beans" name="myinput">
</form>
</body>
el.setSelectionRange(-1, -1);
https://codesandbox.io/s/peaceful-bash-x2mti
Este método actualiza las propiedades HTMLInputElement.selectionStart, selectionEnd y selectionDirection en una llamada.
https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setSelectionRange
En otros métodos js -1
generalmente significa (para) el último carácter. Este es el caso de este también, pero no pude encontrar una mención explícita de este comportamiento en los documentos.
Para todos los navegadores para todos los casos:
function moveCursorToEnd(el) {
window.setTimeout(function () {
if (typeof el.selectionStart == "number") {
el.selectionStart = el.selectionEnd = el.value.length;
} else if (typeof el.createTextRange != "undefined") {
var range = el.createTextRange();
range.collapse(false);
range.select();
}
}, 1);
}
Se requiere tiempo de espera si necesita mover el cursor desde el controlador de eventos onFocus
Me gusta mucho la respuesta aceptada, pero dejó de funcionar en Chrome. En Chrome, para que el cursor llegue al final, el valor de entrada debe cambiar. La solución es la siguiente:
<input id="search" type="text" value="mycurrtext" size="30"
onfocus="var value = this.value; this.value = null; this.value = value;" name="search"/>
En jQuery, eso es
$(document).ready(function () {
$('input').focus(function () {
$(this).attr('value',$(this).attr('value'));
}
}
Este problema es interesante Lo más confuso al respecto es que ninguna solución que encontré resolvió el problema por completo.
+++++++ SOLUCIÓN +++++++
Necesita una función JS, como esta:
function moveCursorToEnd(obj) {
if (!(obj.updating)) {
obj.updating = true;
var oldValue = obj.value;
obj.value = '';
setTimeout(function(){ obj.value = oldValue; obj.updating = false; }, 100);
}
}
Necesitas llamar a este tipo en los eventos onfocus y onclick.
<input type="text" value="Test Field" onfocus="moveCursorToEnd(this)" onclick="moveCursorToEnd(this)">
¡FUNCIONA EN TODOS LOS DISPOSITIVOS Y NAVEGADORES!
Acabo de descubrir que en iOS, la textarea.textContent
propiedad de configuración colocará el cursor al final del texto en el elemento textarea cada vez. El comportamiento fue un error en mi aplicación, pero parece ser algo que podría usar intencionalmente.
var valsrch = $('#search').val();
$('#search').val('').focus().val(valsrch);
Tomando algunas de las respuestas ... haciendo un jquery de una sola línea.
$('#search').focus().val($('#search').val());
Si el campo de entrada solo necesita un valor predeterminado estático, generalmente hago esto con jQuery:
$('#input').focus().val('Default value');
Esto parece funcionar en todos los navegadores.
Si bien esta puede ser una pregunta antigua con muchas respuestas, me encontré con un problema similar y ninguna de las respuestas fue exactamente lo que quería y / o me explicaron mal. El problema con las propiedades selectionStart y selectionEnd es que no existen para el número de tipo de entrada (aunque se hizo la pregunta para el tipo de texto, creo que podría ayudar a otros que podrían tener otros tipos de entrada que necesitan enfocar). Entonces, si no sabe si el tipo de entrada que enfocará la función es un número de tipo o no, no puede usar esa solución.
La solución que funciona entre navegadores y para todos los tipos de entrada es bastante simple:
De esa manera, el cursor está al final del elemento de entrada.
Entonces, todo lo que haría es algo como esto (usando jquery, siempre que se pueda acceder al selector de elementos que se desea enfocar a través del atributo de datos 'elemento de enfoque de datos' del elemento seleccionado y la función se ejecuta después de hacer clic en '.foo' elemento):
$('.foo').click(function() {
element_selector = $(this).attr('data-focus-element');
$focus = $(element_selector);
value = $focus.val();
$focus.focus();
$focus.val(value);
});
¿Por qué funciona esto? Simplemente, cuando se llama a .focus (), el foco se agregará al comienzo del elemento de entrada (que es el problema central aquí), ignorando el hecho de que el elemento de entrada ya tiene un valor. Sin embargo, cuando se cambia el valor de una entrada, el cursor se coloca automáticamente al final del valor dentro del elemento de entrada. Entonces, si anula el valor con el mismo valor que se había ingresado previamente en la entrada, el valor se verá intacto, sin embargo, el cursor se moverá hasta el final.
Pruebe este funciona con Vanilla JavaScript.
<input type="text" id="yourId" onfocus=" let value = this.value; this.value = null; this.value=value" name="nameYouWant" class="yourClass" value="yourValue" placeholder="yourPlaceholder...">
En js
document.getElementById("yourId").focus()
Coloque el cursor cuando haga clic en el área de texto al final del texto ... La variación de este código es ... ¡TAMBIÉN funciona! para Firefox, IE, Safari, Chrome ..
En el código del lado del servidor:
txtAddNoteMessage.Attributes.Add("onClick", "sendCursorToEnd('" & txtAddNoteMessage.ClientID & "');")
En Javascript:
function sendCursorToEnd(obj) {
var value = $(obj).val(); //store the value of the element
var message = "";
if (value != "") {
message = value + "\n";
};
$(obj).focus().val(message);
$(obj).unbind();
}
Si establece el valor primero y luego establece el foco, el cursor siempre aparecerá al final.
$("#search-button").click(function (event) {
event.preventDefault();
$('#textbox').val('this');
$("#textbox").focus();
return false;
});
Aquí está el violín para probar https://jsfiddle.net/5on50caf/1/
Quería poner el cursor al final de un elemento "div" donde contenteditable = true, y obtuve una solución con el código Xeoncross :
<input type="button" value="Paste HTML" onclick="document.getElementById('test').focus(); pasteHtmlAtCaret('<b>INSERTED</b>'); ">
<div id="test" contenteditable="true">
Here is some nice text
</div>
Y esta función hace magia:
function pasteHtmlAtCaret(html) {
var sel, range;
if (window.getSelection) {
// IE9 and non-IE
sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
range = sel.getRangeAt(0);
range.deleteContents();
// Range.createContextualFragment() would be useful here but is
// non-standard and not supported in all browsers (IE9, for one)
var el = document.createElement("div");
el.innerHTML = html;
var frag = document.createDocumentFragment(), node, lastNode;
while ( (node = el.firstChild) ) {
lastNode = frag.appendChild(node);
}
range.insertNode(frag);
// Preserve the selection
if (lastNode) {
range = range.cloneRange();
range.setStartAfter(lastNode);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
}
}
} else if (document.selection && document.selection.type != "Control") {
// IE < 9
document.selection.createRange().pasteHTML(html);
}
}
Funciona bien para la mayoría de los navegadores, verifíquelo, este código coloca el texto y pone el foco al final del texto en el elemento div (no en el elemento de entrada)
https://jsfiddle.net/Xeoncross/4tUDk/
Gracias Xeoncross
También me enfrenté al mismo problema. Finalmente esto va a funcionar para mí:
jQuery.fn.putCursorAtEnd = = function() {
return this.each(function() {
// Cache references
var $el = $(this),
el = this;
// Only focus if input isn't already
if (!$el.is(":focus")) {
$el.focus();
}
// If this function exists... (IE 9+)
if (el.setSelectionRange) {
// Double the length because Opera is inconsistent about whether a carriage return is one character or two.
var len = $el.val().length * 2;
// Timeout seems to be required for Blink
setTimeout(function() {
el.setSelectionRange(len, len);
}, 1);
} else {
// As a fallback, replace the contents with itself
// Doesn't work in Chrome, but Chrome supports setSelectionRange
$el.val($el.val());
}
// Scroll to the bottom, in case we're in a tall textarea
// (Necessary for Firefox and Chrome)
this.scrollTop = 999999;
});
};
Así es como podemos llamar a esto:
var searchInput = $("#searchInputOrTextarea");
searchInput
.putCursorAtEnd() // should be chainable
.on("focus", function() { // could be on any event
searchInput.putCursorAtEnd()
});
Me funciona en safari, IE, Chrome, Mozilla. En dispositivos móviles no probé esto.
//fn setCurPosition
$.fn.setCurPosition = function(pos) {
this.focus();
this.each(function(index, elem) {
if (elem.setSelectionRange) {
elem.setSelectionRange(pos, pos);
} else if (elem.createTextRange) {
var range = elem.createTextRange();
range.collapse(true);
range.moveEnd('character', pos);
range.moveStart('character', pos);
range.select();
}
});
return this;
};
// USAGE - Set Cursor ends
$('#str1').setCurPosition($('#str1').val().length);
// USAGE - Set Cursor at 7 position
// $('#str2').setCurPosition(7);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Set cursor at any position</p>
<p><input type="text" id="str1" value="my string here" /></p>
<p><input type="text" id="str2" value="my string here" /></p>
Súper fácil (puede que tenga que centrarse en el elemento de entrada)
inputEl = getElementById('inputId');
var temp = inputEl.value;
inputEl.value = '';
inputEl.value = temp;
Intenté las sugerencias antes, pero ninguna funcionó para mí (las probé en Chrome), así que escribí mi propio código, y funciona bien en Firefox, IE, Safari, Chrome ...
En Textarea:
onfocus() = sendCursorToEnd(this);
En Javascript:
function sendCursorToEnd(obj) {
var value = obj.value; //store the value of the element
var message = "";
if (value != "") {
message = value + "\n";
};
$(obj).focus().val(message);}
Aquí hay una demostración de jsFiddle de mi respuesta. La demostración utiliza CoffeeScript, pero puede convertirlo a JavaScript simple si es necesario.
La parte importante, en JavaScript:
var endIndex = textField.value.length;
if (textField.setSelectionRange) {
textField.setSelectionRange(endIndex, endIndex);
}
Estoy publicando esta respuesta porque ya la escribí para otra persona que tenía la misma pregunta. Esta respuesta no cubre tantos casos extremos como las respuestas principales aquí, pero funciona para mí y tiene una demo jsFiddle con la que puedes jugar.
Aquí está el código de jsFiddle, por lo que esta respuesta se conserva incluso si jsFiddle desaparece:
moveCursorToEnd = (textField) ->
endIndex = textField.value.length
if textField.setSelectionRange
textField.setSelectionRange(endIndex, endIndex)
jQuery ->
$('.that-field').on 'click', ->
moveCursorToEnd(this)
<div class="field">
<label for="pressure">Blood pressure</label>:
<input class="that-field" type="text" name="pressure" id="pressure" value="24">
</div>
<p>
Try clicking in the text field. The cursor will always jump to the end.
</p>
body {
margin: 1em;
}
.field {
margin-bottom: 1em;
}
Prueba el siguiente código:
$('input').focus(function () {
$(this).val($(this).val());
}).focus()
setSelectionRange
enfoque es ciertamente mucho más eficiente cuando / donde sea compatible.
Aunque estoy respondiendo demasiado tarde, pero para futuras consultas, será útil. Y también funciona encontenteditable
div.
Desde donde necesita establecer el foco al final; escribe este código
var el = document.getElementById("your_element_id");
placeCaretAtEnd(el);
Y la función es -
function placeCaretAtEnd(el) {
el.focus();
if (typeof window.getSelection != "undefined"
&& typeof document.createRange != "undefined") {
var range = document.createRange();
range.selectNodeContents(el);
range.collapse(false);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
} else if (typeof document.body.createTextRange != "undefined") {
var textRange = document.body.createTextRange();
textRange.moveToElementText(el);
textRange.collapse(false);
textRange.select();
}
}