Pregunta

¿Cómo se puede establecer la posición del cursor en un campo de texto con jQuery?Tengo un campo de texto con el contenido, y quiero que los usuarios de cursor para ser colocado en un cierto desplazamiento cuando se centran en el campo.El código debe ser algo como esto:

$('#input').focus(function() {
  $(this).setCursorPosition(4);
});

¿Qué sería de la aplicación de que setCursorPosition función parece?Si había un campo de texto con el contenido abcdefg, llamada podría resultar en que el cursor se coloca de la siguiente manera:abcd**|**efg.

Java tiene una función similar, setCaretPosition.Hace un método similar existe para javascript?

Actualización:He modificado los CMS de código para trabajar con jQuery de la siguiente manera:

new function($) {
  $.fn.setCursorPosition = function(pos) {
    if (this.setSelectionRange) {
      this.setSelectionRange(pos, pos);
    } else if (this.createTextRange) {
      var range = this.createTextRange();
      range.collapse(true);
      if(pos < 0) {
        pos = $(this).val().length + pos;
      }
      range.moveEnd('character', pos);
      range.moveStart('character', pos);
      range.select();
    }
  }
}(jQuery);
¿Fue útil?

Solución

Tengo dos funciones:

function setSelectionRange(input, selectionStart, selectionEnd) {
  if (input.setSelectionRange) {
    input.focus();
    input.setSelectionRange(selectionStart, selectionEnd);
  }
  else if (input.createTextRange) {
    var range = input.createTextRange();
    range.collapse(true);
    range.moveEnd('character', selectionEnd);
    range.moveStart('character', selectionStart);
    range.select();
  }
}

function setCaretToPos (input, pos) {
  setSelectionRange(input, pos, pos);
}

A continuación, puede utilizar setCaretToPos como este:

setCaretToPos(document.getElementById("YOURINPUT"), 4);

Vivo ejemplo con un textarea y un input, mostrando el uso de jQuery:

function setSelectionRange(input, selectionStart, selectionEnd) {
  if (input.setSelectionRange) {
    input.focus();
    input.setSelectionRange(selectionStart, selectionEnd);
  } else if (input.createTextRange) {
    var range = input.createTextRange();
    range.collapse(true);
    range.moveEnd('character', selectionEnd);
    range.moveStart('character', selectionStart);
    range.select();
  }
}

function setCaretToPos(input, pos) {
  setSelectionRange(input, pos, pos);
}

$("#set-textarea").click(function() {
  setCaretToPos($("#the-textarea")[0], 10)
});
$("#set-input").click(function() {
  setCaretToPos($("#the-input")[0], 10);
});
<textarea id="the-textarea" cols="40" rows="4">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</textarea>
<br><input type="button" id="set-textarea" value="Set in textarea">
<br><input id="the-input" type="text" size="40" value="Lorem ipsum dolor sit amet, consectetur adipiscing elit">
<br><input type="button" id="set-input" value="Set in input">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

A partir del 2016, probado y funcionando en Chrome, Firefox, IE11, incluso IE8 (ver la última aquí;Pila de Fragmentos no apoyo IE8).

Otros consejos

Esto es una solución jQuery:

$.fn.selectRange = function(start, end) {
    if(end === undefined) {
        end = start;
    }
    return this.each(function() {
        if('selectionStart' in this) {
            this.selectionStart = start;
            this.selectionEnd = end;
        } else if(this.setSelectionRange) {
            this.setSelectionRange(start, end);
        } else if(this.createTextRange) {
            var range = this.createTextRange();
            range.collapse(true);
            range.moveEnd('character', end);
            range.moveStart('character', start);
            range.select();
        }
    });
};

Con esto, se puede hacer

$('#elem').selectRange(3,5); // select a range of text
$('#elem').selectRange(3); // set cursor position

Las soluciones aquí tienen razón excepto por el código de extensión de jQuery.

La función de extensión debe iterar sobre cada elemento seleccionado y volver this para apoyar encadenamiento. Aquí es la a versión correcta:

$.fn.setCursorPosition = function(pos) {
  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;
};

he encontrado una solución que funciona para mí:

$.fn.setCursorPosition = function(position){
    if(this.length == 0) return this;
    return $(this).setSelection(position, position);
}

$.fn.setSelection = function(selectionStart, selectionEnd) {
    if(this.length == 0) return this;
    input = this[0];

    if (input.createTextRange) {
        var range = input.createTextRange();
        range.collapse(true);
        range.moveEnd('character', selectionEnd);
        range.moveStart('character', selectionStart);
        range.select();
    } else if (input.setSelectionRange) {
        input.focus();
        input.setSelectionRange(selectionStart, selectionEnd);
    }

    return this;
}

$.fn.focusEnd = function(){
    this.setCursorPosition(this.val().length);
            return this;
}

Ahora puede mover el enfoque al final de cualquier elemento llamando a:

$(element).focusEnd();

Esto funcionó para mí en Safari 5 en Mac OS X, jQuery 1.4:

$("Selector")[elementIx].selectionStart = desiredStartPos; 
$("Selector")[elementIx].selectionEnd = desiredEndPos;

Me doy cuenta de que este es un post muy antiguo, pero pensé que debería ofrecer tal vez una solución más simple para actualizarlo usando sólo jQuery.

function getTextCursorPosition(ele) {   
    return ele.prop("selectionStart");
}

function setTextCursorPosition(ele,pos) {
    ele.prop("selectionStart", pos + 1);
    ele.prop("selectionEnd", pos + 1);
}

function insertNewLine(text,cursorPos) {
    var firstSlice = text.slice(0,cursorPos);
    var secondSlice = text.slice(cursorPos);

    var new_text = [firstSlice,"\n",secondSlice].join('');

    return new_text;
}

Uso para el uso de Ctrl-Enter para añadir una nueva línea (como en Facebook):

$('textarea').on('keypress',function(e){
    if (e.keyCode == 13 && !e.ctrlKey) {
        e.preventDefault();
        //do something special here with just pressing Enter
    }else if (e.ctrlKey){
        //If the ctrl key was pressed with the Enter key,
        //then enter a new line break into the text
        var cursorPos = getTextCursorPosition($(this));                

        $(this).val(insertNewLine($(this).val(), cursorPos));
        setTextCursorPosition($(this), cursorPos);
    }
});

Estoy abierto a la crítica. Gracias.

ACTUALIZACIÓN: Esta solución no permite la funcionalidad normal de copiar y pegar para trabajar (es decir, Ctrl + C, Ctrl-V), por lo que tendrá que corregir esto en el futuro para asegurarse de que esa parte funciona de nuevo. Si usted tiene una idea de cómo hacerlo, por favor comentar aquí, y voy a ser feliz para probarlo. Gracias.

En IE para mover el cursor en alguna posición de este código es suficiente:

var range = elt.createTextRange();
range.move('character', pos);
range.select();

Ajuste el enfoque antes de insertar el texto en el área de texto de este modo?

$("#comments").focus();
$("#comments").val(comments);

Esto funciona para mí en cromo

$('#input').focus(function() {
    setTimeout( function() {
        document.getElementById('input').selectionStart = 4;
        document.getElementById('input').selectionEnd = 4;
    }, 1);
});

Al parecer, se necesita un retraso de un microsegundo o más, porque por lo general un usuario se centra en el campo de texto haciendo clic en alguna posición en el campo de texto (o pestaña golpes), que desea anular, por lo que tiene que esperar hasta la posición es fijado por el usuario haga clic y luego cambiarlo.

pequeña modificación en el código que encontré en bitbucket

El código es ahora capaz de seleccionar / culminante con puntos de inicio / final si se le da 2 posiciones. Probado y funciona bien en FF / cromo / IE9 / Opera.

$('#field').caret(1, 9);

El código se enumeran a continuación, sólo unas pocas líneas cambiaron:

(function($) {
  $.fn.caret = function(pos) {
    var target = this[0];
    if (arguments.length == 0) { //get
      if (target.selectionStart) { //DOM
        var pos = target.selectionStart;
        return pos > 0 ? pos : 0;
      }
      else if (target.createTextRange) { //IE
        target.focus();
        var range = document.selection.createRange();
        if (range == null)
            return '0';
        var re = target.createTextRange();
        var rc = re.duplicate();
        re.moveToBookmark(range.getBookmark());
        rc.setEndPoint('EndToStart', re);
        return rc.text.length;
      }
      else return 0;
    }

    //set
    var pos_start = pos;
    var pos_end = pos;

    if (arguments.length > 1) {
        pos_end = arguments[1];
    }

    if (target.setSelectionRange) //DOM
      target.setSelectionRange(pos_start, pos_end);
    else if (target.createTextRange) { //IE
      var range = target.createTextRange();
      range.collapse(true);
      range.moveEnd('character', pos_end);
      range.moveStart('character', pos_start);
      range.select();
    }
  }
})(jQuery)

Sólo recuerde volver falsa justo después de la llamada a la función si utiliza las teclas de flecha desde Chrome Fricks el frack hasta lo contrario.

{
    document.getElementById('moveto3').setSelectionRange(3,3);
    return false;
}

En base a esta pregunta , la respuesta no se trabajar perfectamente para iE y Opera cuando hay nueva línea en el área de texto. La respuesta explicar cómo ajustar la selectionStart, selectionEnd antes de llamar setSelectionRange.

Tengo probar el adjustOffset de la otra pregunta con la solución propuesta por @AVProgrammer y que funcione.

function adjustOffset(el, offset) {
    /* From https://stackoverflow.com/a/8928945/611741 */
    var val = el.value, newOffset = offset;
    if (val.indexOf("\r\n") > -1) {
        var matches = val.replace(/\r\n/g, "\n").slice(0, offset).match(/\n/g);
        newOffset += matches ? matches.length : 0;
    }
    return newOffset;
}

$.fn.setCursorPosition = function(position){
    /* From https://stackoverflow.com/a/7180862/611741 */
    if(this.lengh == 0) return this;
    return $(this).setSelection(position, position);
}

$.fn.setSelection = function(selectionStart, selectionEnd) {
    /* From https://stackoverflow.com/a/7180862/611741 
       modified to fit https://stackoverflow.com/a/8928945/611741 */
    if(this.lengh == 0) return this;
    input = this[0];

    if (input.createTextRange) {
        var range = input.createTextRange();
        range.collapse(true);
        range.moveEnd('character', selectionEnd);
        range.moveStart('character', selectionStart);
        range.select();
    } else if (input.setSelectionRange) {
        input.focus();
        selectionStart = adjustOffset(input, selectionStart);
        selectionEnd = adjustOffset(input, selectionEnd);
        input.setSelectionRange(selectionStart, selectionEnd);
    }

    return this;
}

$.fn.focusEnd = function(){
    /* From https://stackoverflow.com/a/7180862/611741 */
    this.setCursorPosition(this.val().length);
}

que tenía que conseguir este trabajo para los elementos contentEditable y jQuery y tought alguien podría querer dejarlo listo para usar:

$.fn.getCaret = function(n) {
    var d = $(this)[0];
    var s, r;
    r = document.createRange();
    r.selectNodeContents(d);
    s = window.getSelection();
    console.log('position: '+s.anchorOffset+' of '+s.anchorNode.textContent.length);
    return s.anchorOffset;
};

$.fn.setCaret = function(n) {
    var d = $(this)[0];
    d.focus();
    var r = document.createRange();
    var s = window.getSelection();
    r.setStart(d.childNodes[0], n);
    r.collapse(true);
    s.removeAllRanges();
    s.addRange(r);
    console.log('position: '+s.anchorOffset+' of '+s.anchorNode.textContent.length);
    return this;
};

Uso $(selector).getCaret() devuelve el desplazamiento número y $(selector).setCaret(num) establece la offeset y ajusta el enfoque en el elemento.

También un pequeño consejo, si se ejecuta desde la consola <=> devolverá el console.log pero no se visualizará el foco ya que se establece en la ventana de la consola.

Bests; D

Puede cambiar directamente el prototipo si no existe setSelectionRange.

(function() {
    if (!HTMLInputElement.prototype.setSelectionRange) {
        HTMLInputElement.prototype.setSelectionRange = function(start, end) {
            if (this.createTextRange) {
                var range = this.createTextRange();
                this.collapse(true);
                this.moveEnd('character', end);
                this.moveStart('character', start);
                this.select();
            }
        }
    }
})();
document.getElementById("input_tag").setSelectionRange(6, 7);

jsFiddle enlace

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top