Dopo un'attenta revisione, propongo questo come una soluzione molto più pulita all'interno di questo thread:
$("input").focus(function(){
$(this).on("click.a keyup.a", function(e){
$(this).off("click.a keyup.a").select();
});
});
Il problema:
Ecco un po 'di spiegazione:
Innanzitutto, diamo un'occhiata all'ordine degli eventi quando si passa con il mouse o la scheda in un campo.
Possiamo registrare tutti gli eventi rilevanti come questo:
$("input").on("mousedown focus mouseup click blur keydown keypress keyup change",
function(e) { console.log(e.type); });
Nota : ho modificato questa soluzione per usarla click
piuttosto che mouseup
come accade più tardi nella pipeline degli eventi e sembra che stia causando alcuni problemi in Firefox come da commento di @ Jocie
Alcuni browser tentano di posizionare il cursore durante gli eventi mouseup
o click
. Questo ha senso poiché potresti voler avviare il cursore in una posizione e trascinare per evidenziare del testo. Non può fare una designazione sulla posizione del cursore fino a quando non si è effettivamente sollevato il mouse. Quindi le funzioni che gestiscono focus
sono destinate a rispondere troppo presto, lasciando che il browser prevalga sul posizionamento.
Ma il problema è che vogliamo davvero gestire l'evento focus. Ci fa sapere la prima volta che qualcuno è entrato nel campo. Successivamente, non vogliamo continuare a ignorare il comportamento di selezione dell'utente.
La soluzione:
Invece, all'interno del focus
gestore eventi, possiamo collegare rapidamente listener per gli eventi click
(clic in) e keyup
(tab in) che stanno per essere attivati.
Nota : il keyup di un evento tab verrà effettivamente attivato nel nuovo campo di input, non in quello precedente
Vogliamo lanciare l'evento una volta sola. Potremmo usare .one("click keyup)
, ma questo chiamerebbe il gestore eventi una volta per ogni tipo di evento . Invece, non appena si preme il mouse o il keyup chiameremo la nostra funzione. La prima cosa che faremo è rimuovere i gestori per entrambi. In questo modo, non importa se abbiamo inserito il tab o ci siamo sistemati. La funzione dovrebbe essere eseguita esattamente una volta.
Nota : la maggior parte dei browser seleziona naturalmente tutto il testo durante un evento di tabulazione, ma come sottolineato da animatedgif , vogliamo ancora gestire l' keyup
evento, altrimenti l' mouseup
evento continuerà a persistere ogni volta che abbiamo inserito il tab. Ascoltiamo entrambi in modo da poter girare dagli ascoltatori non appena abbiamo elaborato la selezione.
Ora possiamo chiamare select()
dopo che il browser ha effettuato la sua selezione, quindi siamo sicuri di ignorare il comportamento predefinito.
Infine, per una maggiore protezione, possiamo aggiungere spazi dei nomi degli eventi alle funzioni mouseup
e in keyup
modo che il .off()
metodo non rimuova altri ascoltatori che potrebbero essere in riproduzione.
Testato in IE 10+, FF 28+ e Chrome 35+
In alternativa, se si desidera estendere jQuery con una funzione chiamata once
che si attiverà esattamente una volta per qualsiasi numero di eventi :
$.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);
});
};
Quindi puoi semplificare ulteriormente il codice in questo modo:
$("input").focus(function(){
$(this).once("click keyup", function(e){
$(this).select();
});
});