La selezione del testo sullo stato attivo utilizzando jQuery non funziona in Safari e Chrome


85

Ho il seguente codice jQuery (simile a questa domanda ) che funziona in Firefox e IE, ma non funziona (nessun errore, semplicemente non funziona) in Chrome e Safari. Qualche idea per una soluzione alternativa?

$("#souper_fancy").focus(function() { $(this).select() });

Voglio un comportamento esatto in Safari su iPad / iPhone. Non funziona nei browser iPod / iPhone. qualsiasi indizio. La risposta accettata di seguito è solo per Chrome / Safari basato su desktop.
Anand

5
Nota: la risposta accettata qui risolve solo metà del problema. Fa funzionare la selezione, ma rende difficile deselezionarla con i clic successivi. Una soluzione migliore può essere trovata qui: stackoverflow.com/questions/3380458/…
SDC

Risposte:


188

È l'evento onmouseup che causa la deselezione della selezione, quindi devi solo aggiungere:

$("#souper_fancy").mouseup(function(e){
    e.preventDefault();
});

3
Ulteriori informazioni sul bug qui: code.google.com/p/chromium/issues/detail?id=4505
Rajat

Come ottenere lo stesso risultato utilizzando Prototype?
tehfink

Puoi anche provare a collegarti all'evento "clic" ed evitare di dover fare due associazioni.
uglymunky

@uglymunky A seconda di ciò che stai facendo, l'associazione all'evento click non funzionerà in tutti i casi - dopotutto, ci sono altri mezzi per selezionare un campo di input oltre a fare clic su di esso, e vuoi che anche quelli funzionino (ad es. tabbing in esso)
Tacroy,

2
Voglio un comportamento esatto in Safari su iPad / iPhone. Non funziona nei browser iPod / iPhone. qualsiasi indizio.
Anand

25
$('#randomfield').focus(function(event) {
    setTimeout(function() {$('#randomfield').select();}, 0);
});

3
Questa è la risposta migliore se stai cercando di selezionare il testo in un campo modulo per un'app PhoneGap in esecuzione su Android. Ciò fornisce un'indicazione visiva all'utente che il testo è selezionato, mentre la risposta accettata no.
BallisticPugh

4

Questo funziona bene per gli elementi input type = "text". Che tipo di elemento è #souper_fancy?

$("#souper_fancy").focus(function() {
    $(this).select();
});

è un elemento type = "text". Ho provato anche $ ("input [type = text]"). Ancora non funziona con jQuery 1.3.2 in Safari.
user140550

3

Solo impedendo l'impostazione predefinita al mouseup fa sì che la selezione del testo sia sempre attiva. L'evento MOUSEUP è responsabile della cancellazione della selezione del testo. Tuttavia, impedendo il suo comportamento predefinito, non è possibile deselezionare il testo utilizzando il mouse.

Per evitare ciò e far funzionare di nuovo la selezione del testo, è possibile impostare un flag su FOCUS, leggerlo da MOUSEUP e ripristinarlo in modo che gli eventi MOUSEUP futuri funzionino come previsto.

$("#souper_fancy").focus(function() {
    $(this).select();

    //set flag for preventing MOUSEUP event....
    $this.data("preventMouseUp", true);
});

$("#souper_fancy").mouseup(function(e) {
    var preventEvent = $this.data("preventMouseUp");

    //only prevent default if the flag is TRUE
    if (preventEvent) {
        e.preventDefault();
    }

    //reset flag so MOUSEUP event deselect the text
    $this.data("preventMouseUp", false);
});

1

Sebbene funzioni per selezionarlo in IE, Firefox, Chrome, Safari e Opera, non ti consente di modificarlo facendo clic una seconda volta in Firefox, Chrome e Safari. Non del tutto sicuro, ma penso che ciò possa essere dovuto a quei 3 browser che riemettono un evento di attivazione anche se il campo è già attivo, quindi non ti consente mai di inserire effettivamente il cursore (poiché lo stai selezionando di nuovo), mentre in IE e Opera sembra che non lo stia facendo quindi l'evento focus non è stato attivato di nuovo e quindi il cursore viene inserito.

Ho trovato una soluzione migliore in questo post di Stack che non presenta questo problema e funziona in tutti i browser.


1

Questo dovrebbe funzionare anche in Chrome:

$("#souper_fancy").focus(function() {
    var tempSouper = $(this);
    setTimeout(function(){
        tempSouper.select();
    },100);
});

Considera l'idea di aggiungere un feedback costruttivo sul motivo per cui OP vede il problema e la tua soluzione lo risolve.
Mirko Adari

1

Poiché si verifica uno sfarfallio quando si utilizza setTimeout, esiste un'altra soluzione basata sugli eventi. In questo modo l'evento 'focus' attacca l'evento 'mouseup' e il gestore di eventi si scollega di nuovo.

    function selectAllOnFocus(e) {
    if (e.type == "mouseup") { // Prevent default and detach the handler
        console.debug("Mouse is up. Preventing default.");
        e.preventDefault();
        $(e.target).off('mouseup', selectAllOnFocus);
        return;
    }
    $(e.target).select();
    console.debug("Selecting all text");
    $(e.target).on('mouseup', selectAllOnFocus);
}

Quindi cablare il primo evento

    $('.varquantity').on('focus', selectAllOnFocus);

1

Utilizzare setSelectionRange()all'interno di una richiamata per requestAnimationFrame():

$(document).on('focus', '._selectTextOnFocus', (e) => {
    var input = e.currentTarget;
    var initialType = e.currentTarget.type;

    requestAnimationFrame(() => {
        // input.select() is not supported on iOS
        // If setSelectionRange is use on a number input in Chrome it throws an exception,
        // so here we switch to type text first.
        input.type = "text";
        input.setSelectionRange(0, Number.MAX_SAFE_INTEGER || 9999);
        input.type = initialType;
    });
});

Usa setSelectionRange()invece di select()poiché select()non funziona in Safari mobile (vedi Selezione di testo in modo programmatico in un campo di input su dispositivi iOS (Safari mobile) ).

È necessario attendere l'utilizzo requestAnimationFrameprima di selezionare il testo, altrimenti l'elemento non viene fatto scorrere correttamente nella visualizzazione dopo che la tastiera viene visualizzata su iOS.

Quando si utilizza setSelectionRange()è importante impostare il tipo di input su text, altrimenti potrebbe generare eccezioni su Chrome (vedere selectionStart / selectionEnd su input type = "number" non più consentito in Chrome ).


0

Se qualcuno si imbatte di nuovo in questo problema, ho qui una soluzione JS pura che (al momento) funziona su tutti i browser incl. mobile

<input type="text" value="Hello world..." onFocus="window.setTimeout(() => this.select());">

(senza setTimeout () non funziona su Safari, Safari mobile e MS Edge)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.