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();
});
});
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); });
Nota : Alterei esta solução para usar, em click
vez de mouseup
acontecer 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 mouseup
ou 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 focus
destino 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 focus
manipulador 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 keyup
evento, caso contrário, o mouseup
evento 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 mouseup
e keyup
para 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 once
que 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();
});
});