entrada jquery selecionar tudo em foco

327

Estou usando esse código para tentar selecionar todo o texto no campo quando um usuário se concentra no campo. O que acontece é que ele seleciona tudo por um segundo, depois é desmarcado e o cursor de digitação é deixado onde eu cliquei ...

$("input[type=text]").focus(function() {
   $(this).select();
});

Quero que tudo permaneça selecionado.

Tim
fonte
Qual navegador, parece estar funcionando bem para mim no FF?
R0MANARMY
8
Chrome = falha para este
wowo_999 30/06
1
Eu estava usando o Chrome, mas o arquivo .click () resolve o problema :) #
Tim Tim
4
Nota: A resposta aceita aqui resolve apenas metade do problema. Isso faz com que a seleção funcione, mas dificulta a desmarcação com cliques subsequentes. Uma solução melhor pode ser encontrada aqui: stackoverflow.com/questions/3380458/…
SDC

Respostas:

481

Tente usar em clickvez de focus. Parece funcionar para eventos importantes e do mouse (pelo menos no Chrome / Mac):

jQuery <versão 1.7:

$("input[type='text']").click(function () {
   $(this).select();
});

jQuery versão 1.7+:

$("input[type='text']").on("click", function () {
   $(this).select();
});

Aqui está uma demonstração

karim79
fonte
62
o problema é que você não pode mais selecionar parte do texto com o mouse. Quando o clique ocorre, o texto completo é selecionado.
Helin Wang
6
Não é uma solução viável para mim. Isso cria o problema descrito por Wang.
Marquez
1
Existe uma solução abaixo da Nianpeng que também funciona com a seleção de texto do mouse.
Philibert Perusse
4
@AwQiruiGuo $ .fn.on ('clique', ..) pode usar menos memória e trabalhar para elementos filho adicionados dinamicamente.
Ricky Boyce
7
Isso não funciona para focar um campo ao tabular.
Colin Breame
65

Eu acho que o que acontece é o seguinte:

focus()
   UI tasks related to pre-focus
   callbacks
       select()
   UI tasks related to focus (which unselect again)

Uma solução alternativa pode estar chamando o select () de forma assíncrona, para que seja executado completamente após o focus ():

$("input[type=text]").focus(function() { 
    var save_this = $(this);
    window.setTimeout (function(){ 
       save_this.select(); 
    },100);
});
Piskvor saiu do prédio
fonte
3
$ ("input [type = text]"). focus (function () {var save_this = $ (this); window.setTimeout (function () {save_this.select ();}, 100);});
Etienne
@ Etienne: Oh, bom ponto: o tratamento de thisé um pouco inesperado em tais âmbitos. Vou atualizar o código.
Piskvor saiu do prédio 23/11/12
3
um valor de tempo limite 0 também parece bom, e a função "focusin ()" também está trabalhando com esse método.
Tanguy
4
Sim, você nem precisa definir um período. 0 funcionará bem, pois o tempo limite termina no final da pilha de chamadas atual. Isto significa que o foco e clique eventos durante todo o fogo, e então sua função é executada
Joshua Bambrick
1
O tempo limite 0 parece ter o problema de o evento 'click' ser acionado em um quadro posterior, desmarcando a caixa novamente. Acho que tempo limite de 10 parece funcionar muito bem - nenhum atraso perceptível, mas mais confiável do que 0.
philh
57

Eu acho que essa é a melhor solução. Ao contrário de simplesmente selecionar no evento onclick, ele não impede a seleção / edição de texto com o mouse. Ele funciona com os principais mecanismos de renderização, incluindo o IE8.

$('input').on('focus', function (e) {
    $(this)
        .one('mouseup', function () {
            $(this).select();
            return false;
        })
        .select();
});

http://jsfiddle.net/25Mab/9/

user2072367
fonte
4
Isso funciona apenas para campos existentes; aqui está uma atualização para vinculá-lo a novos campos de entrada: jsfiddle.net
adriaan
Às vezes, o foco pode ser dado sem um clique, e isso lida bem. Por causa disso, isso para mim é a resposta mais limpa - embora possa haver alguns pendurados ouvintes de eventos cada vez que a entrada é focado e não por um clique ... muito melhor do que setTimeout
ilovett
Isso não permite que um segundo clique nas entradas numéricas selecione outra parte do texto com o mouse. Remover o segundo select()parece funcionar.
Dperish
Ainda melhor com um adicional$('input[autofocus]').select();
Daniel Bleisteiner 11/03/19
38

Há algumas respostas decentes aqui e @ user2072367 é a minha favorita, mas ele tem um resultado inesperado quando você se concentra na guia e não no clique. (resultado inesperado: para selecionar texto normalmente após o foco na guia, você deve clicar uma vez mais)

Esse violão corrige esse pequeno erro e armazena adicionalmente $ (this) em uma variável para evitar a seleção redundante do DOM. Confira! (:

Testado no IE> 8

$('input').on('focus', function() {
    var $this = $(this)
        .one('mouseup.mouseupSelect', function() {
            $this.select();
            return false;
        })
        .one('mousedown', function() {
            // compensate for untriggered 'mouseup' caused by focus via tab
            $this.off('mouseup.mouseupSelect');
        })
        .select();
});
Gif Animado
fonte
2
Marcar com +1 as soluções da sua e da @ user2072367 são as mais limpas em todo este segmento e eu gostaria que houvesse uma maneira de chegar ao topo mais rapidamente.
precisa saber é o seguinte
1
Até funciona se o usuário tentar selecionar todo o texto, bravo.
precisa saber é
Para mim, isso não funciona no ie11 no Windows 8.1. Ele faz o trabalho em ie11 no Windows 7 e no Windows 10
Lars Thomas Bredland
1
@LarsThomasBredland Acabei de experimentar a vitória 8.1 + ie11 e funciona como esperado. O que "não funciona" para você?
Animated
Apenas não seleciona nada. (I testado em outra win8 e ela não funciona lá - mesmo nível do sistema operacional e versão do IE)
Lars Thomas Bredland
21

Após uma análise cuidadosa, proponho isso como uma solução muito mais limpa dentro deste segmento:

$("input").focus(function(){
    $(this).on("click.a keyup.a", function(e){      
        $(this).off("click.a keyup.a").select();
    });
});

Demonstração em jsFiddle

O problema:

Aqui está um pouco de explicação:

Primeiro, vamos dar uma olhada na ordem dos eventos quando você passa o mouse ou guia em um campo.
Podemos registrar todos os eventos relevantes como este:

$("input").on("mousedown focus mouseup click blur keydown keypress keyup change",
              function(e) { console.log(e.type); });

eventos de foco

Nota : Alterei esta solução para usar, em clickvez de mouseupacontecer mais tarde no pipeline de eventos, e parecia estar causando alguns problemas no firefox, conforme o comentário de @ Jocie

Alguns navegadores tentam posicionar o cursor durante os eventos mouseupou click. Isso faz sentido, pois você pode querer iniciar o cursor em uma posição e arrastar para destacar algum texto. Não pode fazer uma designação sobre a posição do cursor até que você realmente tenha levantado o mouse. Portanto, as funções que lidam com o focusdestino estão fadadas a responder muito cedo, deixando o navegador substituir o seu posicionamento.

Mas o problema é que realmente queremos lidar com o evento de foco. Ele nos informa a primeira vez que alguém entra no campo. Após esse ponto, não queremos continuar substituindo o comportamento de seleção do usuário.

A solução:

Em vez disso, dentro do focusmanipulador de eventos, podemos anexar rapidamente ouvintes para os eventos click(clique) e keyup(tab in) que estão prestes a disparar.

Nota : O keyup de um evento da guia será acionado no novo campo de entrada, não no campo anterior

Queremos apenas disparar o evento uma vez. Poderíamos usar .one("click keyup), mas isso chamaria o manipulador de eventos uma vez para cada tipo de evento . Em vez disso, assim que pressionar o mouse ou a tecla, chamaremos nossa função. A primeira coisa que faremos é remover os manipuladores de ambos. Dessa forma, não importa se inserimos ou inserimos o mouse. A função deve ser executada exatamente uma vez.

Nota : a maioria dos navegadores seleciona naturalmente todo o texto durante um evento de guia, mas, como o gif animado apontou , ainda queremos lidar com o keyupevento, caso contrário, o mouseupevento ainda permanecerá a qualquer momento em que for inserido o guia . Ouvimos os dois para que possamos ativar desligue os ouvintes assim que processarmos a seleção.

Agora, podemos ligar select()depois que o navegador fizer sua seleção, para substituir o comportamento padrão.

Finalmente, para proteção extra, podemos adicionar espaços de nomes de eventos às funções mouseupe keyuppara que o .off()método não remova outros ouvintes que possam estar em jogo.


Testado no IE 10+, FF 28+ e Chrome 35+


Como alternativa, se você deseja estender o jQuery com uma função chamada onceque será acionada exatamente uma vez para qualquer número de eventos :

$.fn.once = function (events, callback) {
    return this.each(function () {
        var myCallback = function (e) {
            callback.call(this, e);
            $(this).off(events, myCallback);
        };
        $(this).on(events, myCallback);
    });
};

Em seguida, você pode simplificar ainda mais o código assim:

$("input").focus(function(){
    $(this).once("click keyup", function(e){      
        $(this).select();
    });
});

Demonstração em violino

KyleMit
fonte
No Firefox 31 no Windows o seu código só seleciona o texto em todos os outros clique quando você clica entre as duas caixas de texto
Vitani
1
@Jocie, não sei por que ele está alternando, mas parece que o FF lida com a seleção de texto no clickevento que está mais abaixo do que no pipeline mouseup. Como queremos lidar com o final da seleção o mais tarde possível para nos dar a maior chance de substituir o navegador, usar o clique em vez da mouse deve fazer o truque. Testado em FF, Chrome e IE.
KyleMit
1
Obrigado! Finalmente, uma solução que realmente funciona e em todos os navegadores!
Vincent
1
Sim! Isso funcionou para mim também! Obrigado. Esta deveria ter sido a resposta oficial #
Fandango68
1
@RiZKiT, onenão o cortará como "O manipulador é executado uma vez por elemento por tipo de evento . Ele desativará automaticamente o evento que o disparou, mas o outro ainda estará por aí e offcuida de ambos. Veja meu pergunta: função que irá disparar apenas uma vez para qualquer número de eventos
KyleMit
13

Isso faria o trabalho e evitaria o problema de que você não pode mais selecionar parte do texto com o mouse.

$("input[type=text]").click(function() {
    if(!$(this).hasClass("selected")) {
        $(this).select();
        $(this).addClass("selected");
    }
});
$("input[type=text]").blur(function() {
    if($(this).hasClass("selected")) {
        $(this).removeClass("selected");
    }
});
Nianpeng
fonte
1
Importante para manter a capacidade de selecionar parte do texto com o mouse. Eu estou usando este e sua A1
Philibert Perusse
2
Muita coisa acontecendo aqui, o uso de user2072367 solução foco / mouseup
George
@George user2072367's é muito bom, mas tem algumas falhas sérias. Confira minha solução (:
animatedgif
6

Esta versão funciona no ios e também corrige o arrastar-para-selecionar padrão no windows chrome

var srcEvent = null;

$("input[type=text],input[type=number]")

    .mousedown(function (event) {
        srcEvent = event;
    })

    .mouseup(function (event) {
        var delta = Math.abs(event.clientX - srcEvent.clientX) 
                  + Math.abs(event.clientY - srcEvent.clientY);

        var threshold = 2;
        if (delta <= threshold) {
                   try {
                        // ios likes this but windows-chrome does not on number fields
                        $(this)[0].selectionStart = 0;
                        $(this)[0].selectionEnd = 1000;
                    } catch (e) {
                        // windows-chrome likes this
                        $(this).select();
                    }
        }
    });

http://jsfiddle.net/Zx2sc/2/

anihilnine
fonte
Editado para acrescentar tentativa feio / catch para apaziguar os navegadores
anihilnine
5

O problema com a maioria dessas soluções é que elas não funcionam corretamente ao alterar a posição do cursor no campo de entrada.

O onmouseupevento altera a posição do cursor no campo, que é acionado depois onfocus(pelo menos no Chrome e FF). Se você descartar incondicionalmente omouseup , o usuário não poderá alterar a posição do cursor com o mouse.

function selectOnFocus(input) {
    input.each(function (index, elem) {
        var jelem = $(elem);
        var ignoreNextMouseUp = false;

        jelem.mousedown(function () {
            if (document.activeElement !== elem) {
                ignoreNextMouseUp = true;
            }
        });
        jelem.mouseup(function (ev) {
            if (ignoreNextMouseUp) {
                ev.preventDefault();
                ignoreNextMouseUp = false;
            }
        });
        jelem.focus(function () {
            jelem.select();
        });
    });
}
selectOnFocus($("#myInputElement"));

O código impedirá condicionalmente o mouseup comportamento padrão se o campo não tiver foco no momento. Funciona para estes casos:

  • clicando quando o campo não está focado
  • clicando quando o campo tem foco
  • tabulação no campo

Eu testei isso no Chrome 31, FF 26 e IE 11.

Colin Breame
fonte
Isso funciona perfeitamente para eventos de clique, mas se eu usar guia para mover para o próximo campo de entrada vejo que o conteúdo é selecionado e de-selecionado apenas mais tarde
ToX 82
4

Encontrei uma solução incrível lendo este tópico

$(function(){

    jQuery.selectText('input:text');
    jQuery.selectText('input:password');

});

jQuery.extend( {
    selectText: function(s) { 
        $(s).live('focus',function() {
            var self = $(this);
            setTimeout(function() {self.select();}, 0);
        });
    }
});
RafaelTSCS
fonte
... que é essencialmente a mesma resposta que a de Piskvor .
613 Oliver
não se esqueça de todos os outros tipos de texto HTML5, por exemplo, 'input [type = email]' #
jamiebarrow
3

Eu venho do final de 2016 e esse código funciona nas versões recentes do jquery (jquery-2.1.3.js nesse caso).

if ($(element).is("input")) {
    $(element).focus(function () {
        $(element).select();
    });
}
Aaron
fonte
2

Eu usando o FF 16.0.2 e jquery 1.8.3, todo o código na resposta não funcionou.
Eu uso código como este e trabalho.

$("input[type=text]").focus().select();
GusDeCooL
fonte
4
Isso não responde à pergunta, que é como selecionar o conteúdo de uma caixa de entrada quando o usuário focaliza o campo . Isso irá focar imediatamente e selecionar o código, sem a entrada do usuário.
Sal14
Saluce @ eu não entendo o que você quer dizer? o que o questionador deseja é quando ele seleciona o campo, todo o texto atual é selecionado. E meu código deveria fazer isso. Eu até o uso no meu projeto, como o momento em que escrevo esta resposta.
GusDeCooL
1
Esse código focará e selecionará tudo quando for executado, mas o código, por si só, não está vinculado a um evento gerado pelo usuário , como clicar na caixa de texto. Por exemplo, $("input[type=text]").on('click', function () { $(this).focus.select(); })está causando o foco e a seleção quando o usuário clica na caixa, porque é executado quando o usuário clica na caixa. Sem o manipulador de eventos, o código não responde à pergunta, portanto, o voto negativo e o comentário. Basicamente, você tem a parte "todo o texto atual está selecionado", mas não a parte "quando ele seleciona o campo".
Saldar
1
@GusDeCooL curiosamente (embora este não é exatamente o que ele pediu) que eu queria mesmo resultado que você fez neste :)
Robbie Averill
2
var timeOutSelect;
$("input[type=text]").focus(function() { 
        var save_this = $(this);
        clearTimeout(timeOutSelect);
        timeOutSelect = window.setTimeout (function(){ 
                save_this.select(); 
        }, 100);
});

Use clearTimeout para obter mais segurança se você alternar rapidamente entre duas entradas. ClearTimeout limpa o tempo limite antigo ...

asimov
fonte
Edite com mais informações. As respostas somente código e "tente isso" são desencorajadas, porque não contêm conteúdo pesquisável e não explicam por que alguém deveria "tentar fazer isso". Nós fazemos um esforço aqui para ser um recurso para o conhecimento.
Brian Tompsett -
2

Funciona muito bem com o JavaScript nativo select().

$("input[type=text]").focus(function(event) {
   event.currentTarget.select();
});

ou em geral:

$("input[type=text]")[0].select()
Tobi G.
fonte
1

Ou você pode simplesmente usar o <input onclick="select()">Works perfect.

tectiv3
fonte
não, não faz. funciona para selecionar o todo. mas tente selecionar uma parte do texto manualmente, você não poderá fazer isso.
Sujay Phadke
1

Você pode usar um código simples:

$('#idname').select();
Rubén Ruíz
fonte
Com o uso de jQuery obviamente
Rubén Ruíz
0
<script>$.ready( $("input[type=text]").attr("onclick" , "this.select()"));<script>
trikon
fonte
Provavelmente, isso será marcado como uma resposta de baixa qualidade, porque não tem explicação do que está acontecendo.
Tumultous_rooster 02/04
O seu $.readynão está correto. Você precisa passar uma função para atrasar attraté que o documento esteja pronto. Você está fazendo isso imediatamente e passando a coleção de elementos para $.ready.
Doug65536
Além disso, evite 'onclick', principalmente dessa maneira. Use addEventListener.
Doug65536 02/04
0

Eu sempre uso requestAnimationFrame()para pular mecanismos internos pós-evento e isso funciona perfeitamente no Firefox. Não testou no Chrome.

$("input[type=text]").on('focus', function() {
    requestAnimationFrame(() => $(this).select());
});
RP Pedraza
fonte