Defina o foco do mouse e mova o cursor para o final da entrada usando jQuery


94

Esta pergunta foi feita em alguns formatos diferentes, mas não consigo fazer com que nenhuma das respostas funcione em meu cenário.

Estou usando o jQuery para implementar o histórico de comandos quando o usuário pressiona as setas para cima / para baixo. Quando a seta para cima é pressionada, substituo o valor de entrada pelo comando anterior e defino o foco no campo de entrada, mas quero que o cursor sempre seja posicionado no final da string de entrada.

Meu código, como é:

$(document).keydown(function(e) {
  var key   = e.charCode ? e.charCode : e.keyCode ? e.keyCode : 0;
  var input = self.shell.find('input.current:last');

  switch(key) {
    case 38: // up
      lastQuery = self.queries[self.historyCounter-1];
      self.historyCounter--;
      input.val(lastQuery).focus();
// and it continues on from there

Como posso forçar o cursor a ser colocado no final da 'entrada' após o foco?

Respostas:


143

Parece que limpar o valor depois de focar e redefinir funciona.

input.focus();
var tmpStr = input.val();
input.val('');
input.val(tmpStr);

4
Esta é a única solução que consegui encontrar que funciona em vários navegadores. Parabéns para você!
Meshaal

2
Isso funciona bem com FF e chrome, mas não no IE .. alguém sabe como resolver esse problema no IE?
john Smith de

1
Observe também que você pode encadear as ligações:var temp = input.focus().val(); input.val('').val(temp);
harpo

20
Isso pode ficar ainda mais simples:input.focus().val(input.val());
Fateh Khalsa

2
Não parece funcionar com contenteditableelementos por algum motivo, talvez porque seja necessário usar em .html()vez de.val()
jg2703

55

Parece um pouco estranho, até bobo, mas isso está funcionando para mim:

input.val(lastQuery);
input.focus().val(input.val());

Agora, não tenho certeza se repliquei sua configuração. Estou assumindo que inputé um <input>elemento.

Ao reconfigurar o valor (para ele mesmo), acho que o cursor está sendo colocado no final da entrada. Testado no Firefox 3 e MSIE7.


1
Sim, a entrada é um elemento <input>. Eu tentei isso e não funcionou no FF3 ou Safari 4
jerodsanto

alguma atualização disso? Funcionou para mim. Atualize a pergunta ou adicione uma resposta se você encontrou uma solução.
artlung

Em FF15, isso define o cursor para o início do campo de entrada. Fora isso, está funcionando bem. Você também tem uma solução para o FF?
JochenJung

@JochenJung Eu não olhava para isso desde 2009 - funcionava então com FF3 e jQuery. Se você encontrar uma solução usando jQuery e FF15 atuais, sinta-se à vontade para editar este post.
artlung

44

Espero que isso ajude você:

var fieldInput = $('#fieldName');
var fldLength= fieldInput.val().length;
fieldInput.focus();
fieldInput[0].setSelectionRange(fldLength, fldLength);

4
Funciona bem, acho que essa é uma solução melhor do que redefinir o valor, especialmente quando há algum tipo de vinculação de visualização de modelo.
morten.c

2
Esta é a resposta certa, definindo exatamente o que você deseja definir sem errar.
Dan Barron

14

Chris Coyier tem um mini plugin jQuery para isso que funciona perfeitamente bem: http://css-tricks.com/snippets/jquery/move-cursor-to-end-of-textarea-or-input/

Ele usa setSelectionRange se houver suporte, caso contrário, tem um fallback sólido.

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;
  });
};

Então você pode apenas fazer:

input.putCursorAtEnd();

Muito obrigado, a única solução que encontrei em 2020 que parece funcionar de forma confiável.
AdamJones

12

Que tal em uma única linha ...

$('#txtSample').focus().val($('#txtSample').val());

Esta linha funciona para mim.


Obrigado Mad pelo comentário
Chris Rosete

8

2 resposta do artlung : Funciona com a segunda linha apenas no meu código (IE7, IE8; Jquery v1.6):

var input = $('#some_elem');
input.focus().val(input.val());

Adição: se o elemento de entrada foi adicionado ao DOM usando JQuery, um foco não é definido no IE. Eu usei um pequeno truque:

input.blur().focus().val(input.val());

1
Isso meio que funcionou para mim, mas eu tive que fazer algo como: var input = $ ("# inputID"); tmp = input.val (); input.focus (). val (""). blur (). focus (). val (tmp);
will824

@ will824 sua solução de comentários funcionou para mim. Estou postando como resposta.
Aamir Shahzad

8

Ref: @ will824 Comentário, Esta solução funcionou para mim sem problemas de compatibilidade. O resto das soluções falhou no IE9.

var input = $("#inputID");
var tmp = input.val();
input.focus().val("").blur().focus().val(tmp);

Testado e encontrado funcionando em:

Firefox 33
Chrome 34
Safari 5.1.7
IE 9

6

Eu sei que essa resposta chega tarde, mas posso ver que as pessoas não encontraram uma resposta. Para evitar que a tecla up coloque o cursor no início, apenas a return falsepartir do método que trata do evento. Isso interrompe a cadeia de eventos que leva ao movimento do cursor. Colando o código revisado do OP abaixo:

$(document).keydown(function(e) {
  var key   = e.charCode ? e.charCode : e.keyCode ? e.keyCode : 0;
  var input = self.shell.find('input.current:last');

  switch(key) {
    case 38: // up
      lastQuery = self.queries[self.historyCounter-1];
      self.historyCounter--;
      input.val(lastQuery).focus();
      // HERE IS THE FIX:
      return false; 
// and it continues on from there

1
Você pode reduzir a segunda linha paravar key = e.charCode || e.keyCode || 0;
Gone Coding

6

Eu uso o código abaixo e funciona bem

function to_end(el) {
            var len = el.value.length || 0;
            if (len) {
                if ('setSelectionRange' in el) el.setSelectionRange(len, len);
                else if ('createTextRange' in el) {// for IE
                    var range = el.createTextRange();
                    range.moveStart('character', len);
                    range.select();
                }
            }
        }

6

Será diferente para navegadores diferentes:

Isso funciona em ff:

    var t =$("#INPUT");
    var l=$("#INPUT").val().length;
    $(t).focus();

    var r = $("#INPUT").get(0).createTextRange();
    r.moveStart("character", l); 
    r.moveEnd("character", l);      
    r.select();

Mais detalhes estão nestes artigos aqui em SitePoint , AspAlliance .


3

como outro dito, limpar e preencher funcionou para mim:

    var elem = $('#input_field');
    var val = elem.val();
    elem.focus().val('').val(val);

3

defina o valor primeiro. em seguida, defina o foco. quando focar, ele usará o valor que existe no momento do foco, portanto, seu valor deve ser definido primeiro.

essa lógica funciona para mim com um aplicativo que preenche um <input>com o valor de um clicado <button>. val()é definido primeiro. entãofocus()

$('button').on('click','',function(){
    var value = $(this).attr('value');
    $('input[name=item1]').val(value);
    $('input[name=item1]').focus();
});

Você pode simplificar uma linha em vez de duas:$('input[name=item1]').val(value).focus();
emMILD

2

Eu encontrei a mesma coisa sugerida acima por algumas pessoas. Se você focus()primeiro, em seguida, colocar o val()na entrada, o cursor será posicionado no final do valor de entrada no Firefox, Chrome e IE. Se você colocar o val()no campo de entrada primeiro, o Firefox e o Chrome posicionarão o cursor no final, mas o IE o posicionará para frente quando você focus().

$('element_identifier').focus().val('some_value') 

deve fazer o truque (sempre fez para mim de qualquer maneira).


2

No primeiro, você deve definir o foco no objeto de caixa de texto selecionado e, em seguida, definir o valor.

$('#inputID').focus();
$('#inputID').val('someValue')

1
Eu tentei isso, mas não funcionou. Também funciona para você com um conteúdo div editável definido como verdadeiro?
Rupam Datta de

1
    function focusCampo(id){
        var inputField = document.getElementById(id);
        if (inputField != null && inputField.value.length != 0){
            if (inputField.createTextRange){
                var FieldRange = inputField.createTextRange();
                FieldRange.moveStart('character',inputField.value.length);
                FieldRange.collapse();
                FieldRange.select();
            }else if (inputField.selectionStart || inputField.selectionStart == '0') {
                var elemLen = inputField.value.length;
                inputField.selectionStart = elemLen;
                inputField.selectionEnd = elemLen;
                inputField.focus();
            }
        }else{
            inputField.focus();
        }
    }

$('#urlCompany').focus(focusCampo('urlCompany'));

funciona para todos os navegadores, por exemplo.


1

Aqui está outro, um liner que não reatribui o valor:

$("#inp").focus()[0].setSelectionRange(99999, 99999);

0
function CurFocus()
{
    $('.txtEmail').focus(); 
}

function pageLoad()
{
   setTimeout(CurFocus(),3000);
}

window.onload = pageLoad;

0

A resposta do scorpion9 funciona. Só para deixar mais claro, veja meu código abaixo,

<script src="~/js/jquery.js"></script> 
<script type="text/javascript">
    $(function () {
        var input = $("#SomeId");
        input.focus();
        var tmpStr = input.val();
        input.val('');
        input.val(tmpStr);
    });
</script>

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.