Establecer la posición del teclado en el cuadro de texto html

Respuestas:

205

Extraído de la posición de configuración de teclado de Josh Stodola en un cuadro de texto o área de texto con Javascript

Una función genérica que le permitirá insertar el cursor en cualquier posición de un cuadro de texto o área de texto que desee:

function setCaretPosition(elemId, caretPos) {
    var elem = document.getElementById(elemId);

    if(elem != null) {
        if(elem.createTextRange) {
            var range = elem.createTextRange();
            range.move('character', caretPos);
            range.select();
        }
        else {
            if(elem.selectionStart) {
                elem.focus();
                elem.setSelectionRange(caretPos, caretPos);
            }
            else
                elem.focus();
        }
    }
}

El primer parámetro esperado es la ID del elemento en el que desea insertar el cursor de teclado. Si no se puede encontrar el elemento, no pasará nada (obviamente). El segundo parámetro es el índice de posición de caret. Zero pondrá el teclado al principio. Si pasa un número mayor que el número de caracteres en el valor de los elementos, colocará el cursor al final.

Probado en IE6 y versiones posteriores, Firefox 2, Opera 8, Netscape 9, SeaMonkey y Safari. Lamentablemente, en Safari no funciona en combinación con el evento onfocus).

Un ejemplo del uso de la función anterior para obligar al teclado a saltar al final de todas las áreas de texto en la página cuando reciben el foco:

function addLoadEvent(func) {
    if(typeof window.onload != 'function') {
        window.onload = func;
    }
    else {
        if(func) {
            var oldLoad = window.onload;

            window.onload = function() {
                if(oldLoad)
                        oldLoad();

                func();
            }
        }
    }
}

// The setCaretPosition function belongs right here!

function setTextAreasOnFocus() {
/***
 * This function will force the keyboard caret to be positioned
 * at the end of all textareas when they receive focus.
 */
    var textAreas = document.getElementsByTagName('textarea');

    for(var i = 0; i < textAreas.length; i++) {
        textAreas[i].onfocus = function() {
            setCaretPosition(this.id, this.value.length);
        }
    }

    textAreas = null;
}

addLoadEvent(setTextAreasOnFocus);
Ta01
fuente
44
if(elem.selectionStart)se rompe cuando selectionStart es 0, como también lo señala la respuesta de jhnns.
mpartel
1
Esto no funciona para mi. Cuando hago clic en el cuadro de texto real que tengo, espero que la posición del cursor sea al principio. Mira mi violín jsfiddle.net/khx2w
elad.chen
La función setCaretPosition funciona bien. Su función addActionHandler, sin embargo, no lo hace. Pero incluso sin eso, no podría mover el cursor al enfocar. Lo más probable es que el navegador establezca la posición del cursor en función de la posición del clic. No parece haber una forma de evitarlo por lo que puedo decir, pero podría estar completamente equivocado.
GJK
Funciona en IE9, FF25, pero no en Chrome 30. ¡Mejor que nada!
Umber Ferrule
Tengo elem.value = elem.value.replace(/^9/g,'+79')en el código. En el cursor OperaMINI después +. esta función no ayuda
eri
52

El enlace en la respuesta está roto, este debería funcionar (todos los créditos van a blog.vishalon.net ):

http://snipplr.com/view/5144/getset-cursor-in-html-textarea/

En caso de que el código se pierda nuevamente, estas son las dos funciones principales:

function doGetCaretPosition(ctrl)
{
 var CaretPos = 0;

 if (ctrl.selectionStart || ctrl.selectionStart == 0)
 {// Standard.
  CaretPos = ctrl.selectionStart;
 }
 else if (document.selection)
 {// Legacy IE
  ctrl.focus ();
  var Sel = document.selection.createRange ();
  Sel.moveStart ('character', -ctrl.value.length);
  CaretPos = Sel.text.length;
 }

 return (CaretPos);
}


function setCaretPosition(ctrl,pos)
{
 if (ctrl.setSelectionRange)
 {
  ctrl.focus();
  ctrl.setSelectionRange(pos,pos);
 }
 else if (ctrl.createTextRange)
 {
  var range = ctrl.createTextRange();
  range.collapse(true);
  range.moveEnd('character', pos);
  range.moveStart('character', pos);
  range.select();
 }
}
eterno
fuente
1
+1 para las funciones básicas, aunque deben hacerse algunos ajustes . El número de líneas debe sustraerse de "pos", cuando se utiliza el método de rango.
Rob W
36

Como realmente necesitaba esta solución, y la solución de línea de base típica ( enfocar la entrada, luego establecer el valor igual a sí mismo ) no funciona en varios navegadores , pasé un tiempo ajustando y editando todo para que funcione. Sobre la base del código de @ kd7 , esto es lo que se me ocurrió.

¡Disfrutar! Funciona en IE6 +, Firefox, Chrome, Safari, Opera

Técnica de posicionamiento de intercalación entre navegadores (ejemplo: mover el cursor al FIN)

// ** USEAGE ** (returns a boolean true/false if it worked or not)
// Parameters ( Id_of_element, caretPosition_you_want)

setCaretPosition('IDHERE', 10); // example

La carne y las papas son básicamente setCaretPosition de @ kd7 , con el mayor ajuste if (el.selectionStart || el.selectionStart === 0), en firefox, la selección Start está comenzando en 0 , que en booleano, por supuesto, se está convirtiendo en False, por lo que se rompió allí.

En Chrome, el mayor problema era que simplemente no .focus()era suficiente (¡seguía seleccionando TODO el texto!) Por lo tanto, establecemos el valor de sí mismo, el.value = el.value;antes de llamar a nuestra función, y ahora tiene una comprensión y posición con el entrada para usar selectionStart .

function setCaretPosition(elemId, caretPos) {
    var el = document.getElementById(elemId);

    el.value = el.value;
    // ^ this is used to not only get "focus", but
    // to make sure we don't have it everything -selected-
    // (it causes an issue in chrome, and having it doesn't hurt any other browser)

    if (el !== null) {

        if (el.createTextRange) {
            var range = el.createTextRange();
            range.move('character', caretPos);
            range.select();
            return true;
        }

        else {
            // (el.selectionStart === 0 added for Firefox bug)
            if (el.selectionStart || el.selectionStart === 0) {
                el.focus();
                el.setSelectionRange(caretPos, caretPos);
                return true;
            }

            else  { // fail city, fortunately this never happens (as far as I've tested) :)
                el.focus();
                return false;
            }
        }
    }
}
Mark Pieszak - Trilon.io
fuente
@mcpDESIGNS Estoy tratando de usar esta función cuando me enfoco en una entrada de texto, pero no llego a ninguna parte. ¿Podrían ayudarme a aplicar esta función usando javascript puro?
elad.chen
@ elad.chen ¿Está tratando de colocarlos al final del cuadro de texto tan pronto como se centran en él?
Mark Pieszak - Trilon.io
@mcpDESIGNS Quiero colocar el cursor al comienzo del campo tan pronto como el elemento esté siendo enfocado. Vea el violín: jsfiddle.net/KuLTU/3
elad.chen
@ elad.chen ¡Perdón por la alocada respuesta tardía! Simplemente cambie ese evento a en .onclicklugar de .onfocusdentro de su función search_field_focus
Mark Pieszak - Trilon.io
2
el.value = el.value; [...] if(el !== null)- Cambiaría estas dos líneas. Si eles nulo, el.value = el.valuefallará, por lo que esa línea debe estar dentro de if.
BackSlash
21

Ajusté un poco la respuesta de kd7 porque elem.selectionStart se evaluará como falso cuando el selectionStart es incidentalmente 0.

function setCaretPosition(elem, caretPos) {
    var range;

    if (elem.createTextRange) {
        range = elem.createTextRange();
        range.move('character', caretPos);
        range.select();
    } else {
        elem.focus();
        if (elem.selectionStart !== undefined) {
            elem.setSelectionRange(caretPos, caretPos);
        }
    }
}
Johannes Ewald
fuente
5

Encontré una manera fácil de solucionar este problema, probado en IE y Chrome:

function setCaret(elemId, caret)
 {
   var elem = document.getElementById(elemId);
   elem.setSelectionRange(caret, caret);
 }

Pase el id. Del cuadro de texto y la posición del cursor a esta función.

Iam_NSA
fuente
3

Si necesita enfocar un cuadro de texto y su único problema es que todo el texto se resalta mientras desea que el cursor esté al final, entonces, en ese caso específico, puede usar este truco para establecer el valor del cuadro de texto en sí mismo después del enfoque:

$("#myinputfield").focus().val($("#myinputfield").val());
manish_s
fuente
2
<!DOCTYPE html>
<html>
<head>
<title>set caret position</title>
<script type="application/javascript">
//<![CDATA[
window.onload = function ()
{
 setCaret(document.getElementById('input1'), 13, 13)
}

function setCaret(el, st, end)
{
 if (el.setSelectionRange)
 {
  el.focus();
  el.setSelectionRange(st, end);
 }
 else
 {
  if (el.createTextRange)
  {
   range = el.createTextRange();
   range.collapse(true);
   range.moveEnd('character', end);
   range.moveStart('character', st);
   range.select();
  }
 }
}
//]]>
</script>
</head>
<body>

<textarea id="input1" name="input1" rows="10" cols="30">Happy kittens dancing</textarea>

<p>&nbsp;</p>

</body>
</html>
DIpak
fuente
2
function SetCaretEnd(tID) {
    tID += "";
    if (!tID.startsWith("#")) { tID = "#" + tID; }
    $(tID).focus();
    var t = $(tID).val();
    if (t.length == 0) { return; }
    $(tID).val("");
    $(tID).val(t);
    $(tID).scrollTop($(tID)[0].scrollHeight); }
Keith Cromm
fuente
TypeError no capturado: el objeto [object HTMLInputElement] no tiene ningún método 'comienza con'
bobpaul
1
@bobpaul: tIDdebe ser la identificación del elemento, no el objeto del elemento en sí. Si está pasando el objeto elemento, puede eliminar las 2 primeras líneas de este método y funcionará.
temor
2

Me gustaría arreglar las condiciones como a continuación:

function setCaretPosition(elemId, caretPos)
{
 var elem = document.getElementById(elemId);
 if (elem)
 {
  if (typeof elem.createTextRange != 'undefined')
  {
   var range = elem.createTextRange();
   range.move('character', caretPos);
   range.select();
  }
  else
  {
   if (typeof elem.selectionStart != 'undefined')
    elem.selectionStart = caretPos;
   elem.focus();
  }
 }
}
Alexander Gavriliuk
fuente