Después de una revisión cuidadosa, propongo esto como una solución mucho más limpia dentro de este hilo:
$("input").focus(function(){
$(this).on("click.a keyup.a", function(e){
$(this).off("click.a keyup.a").select();
});
});
El problema:
Aquí hay una pequeña explicación:
Primero, echemos un vistazo al orden de los eventos cuando coloca el mouse o la pestaña en un campo.
Podemos registrar todos los eventos relevantes como este:
$("input").on("mousedown focus mouseup click blur keydown keypress keyup change",
function(e) { console.log(e.type); });
Nota : He cambiado esta solución para usarla en click
lugar de mouseup
como sucede más adelante en la canalización del evento y parece estar causando algunos problemas en Firefox según el comentario de @ Jocie.
Algunos navegadores intentan colocar el cursor durante los eventos mouseup
o click
. Esto tiene sentido ya que es posible que desee iniciar el símbolo de intercalación en una posición y arrastrar para resaltar un texto. No puede hacer una designación sobre la posición del símbolo de intercalación hasta que haya levantado el mouse. Por lo tanto, las funciones que manejan focus
están destinadas a responder demasiado pronto, dejando que el navegador anule su posicionamiento.
Pero el problema es que realmente queremos manejar el evento de enfoque. Nos permite saber la primera vez que alguien ingresa al campo. Después de ese punto, no queremos seguir anulando el comportamiento de selección del usuario.
La solución:
En cambio, dentro del focus
controlador de eventos, podemos adjuntar rápidamente oyentes para los eventos click
(hacer clic) y keyup
(tabular) que están a punto de activarse.
Nota : La tecla de un evento de tabulación se activará en el nuevo campo de entrada, no en el anterior.
Solo queremos disparar el evento una vez. Podríamos usar .one("click keyup)
, pero esto llamaría al controlador de eventos una vez para cada tipo de evento . En cambio, tan pronto como se presione el botón mouseup o keyup, llamaremos a nuestra función. Lo primero que haremos es eliminar los controladores de ambos. De esa manera no importará si usamos la pestaña o el mouse. La función debería ejecutarse exactamente una vez.
Nota : la mayoría de los navegadores seleccionan naturalmente todo el texto durante un evento de tabulación, pero como señaló animatedgif , aún queremos manejar el keyup
evento, de lo contrario, el mouseup
evento seguirá persistiendo en cualquier momento en que ingresemos. Escuchamos ambos para poder convertir fuera de los oyentes tan pronto como hayamos procesado la selección.
Ahora, podemos llamar select()
después de que el navegador haya realizado su selección, por lo que estamos seguros de anular el comportamiento predeterminado.
Finalmente, para mayor protección, podemos agregar espacios de nombres de eventos a las funciones mouseup
y keyup
para que el .off()
método no elimine ningún otro detector que pueda estar en juego.
Probado en IE 10+, FF 28+ y Chrome 35+
Alternativamente, si desea extender jQuery con una función llamada once
que se activará exactamente una vez para cualquier 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);
});
};
Entonces puede simplificar el código aún más así:
$("input").focus(function(){
$(this).once("click keyup", function(e){
$(this).select();
});
});