Seleccionar texto en foco usando jQuery no funciona en Safari y Chrome

85

Tengo el siguiente código jQuery (similar a esta pregunta ) que funciona en Firefox e IE, pero falla (no hay errores, simplemente no funciona) en Chrome y Safari. ¿Alguna idea para una solución alternativa?

$("#souper_fancy").focus(function() { $(this).select() });
usuario140550
fuente
Quiero comportamiento exacto en safari de iPad / iPhone. Esto no funciona en los navegadores de iPod / iPhone. Cualquier pista. La respuesta aceptada a continuación es solo para Chrome / Safari basado en escritorio.
Anand
5
Nota: La respuesta aceptada aquí solo resuelve la mitad del problema. Hace que la selección funcione, pero dificulta la eliminación de la selección con los siguientes clics. Puede encontrar una mejor solución aquí: stackoverflow.com/questions/3380458/…
SDC

Respuestas:

188

Es el evento onmouseup el que está provocando que la selección no se seleccione, por lo que solo necesita agregar:

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

fuente
3
Más información sobre el error aquí: code.google.com/p/chromium/issues/detail?id=4505
Rajat
¿Cómo lograr lo mismo usando Prototype?
tehfink
También puede intentar vincular al evento 'click' y evitar tener que hacer dos vinculaciones.
uglymunky
@uglymunky Dependiendo de lo que esté haciendo, la vinculación al evento de clic no funcionará en todos los casos; después de todo, hay otras formas de seleccionar un campo de entrada que hacer clic en él, y desea que también funcionen (por ejemplo, tabulación en él)
Tacroy
2
Quiero comportamiento exacto en safari de iPad / iPhone. Esto no funciona en los navegadores de iPod / iPhone. Cualquier pista.
Anand
25
$('#randomfield').focus(function(event) {
    setTimeout(function() {$('#randomfield').select();}, 0);
});
Alex0007
fuente
3
Esta es la mejor respuesta si está intentando seleccionar texto en un campo de formulario para una aplicación PhoneGap que se ejecuta en Android. Esto le da una indicación visual al usuario de que el texto está seleccionado, mientras que la respuesta aceptada no.
BallisticPugh
4

Esto funciona bien para elementos input type = "text". ¿Qué tipo de elemento es #souper_fancy?

$("#souper_fancy").focus(function() {
    $(this).select();
});
Joe Chung
fuente
es un elemento type = "text". También probé $ ("input [type = text]"). Todavía no funciona con jQuery 1.3.2 en Safari.
user140550
3

El solo hecho de evitar el valor predeterminado al mover el mouse hacia arriba hace que la selección de texto esté ACTIVADA en todo momento. El evento MOUSEUP es responsable de borrar la selección de texto. Sin embargo, al evitar su comportamiento predeterminado, no puede deseleccionar el texto con el mouse.

Para evitar eso y hacer que la selección de texto vuelva a funcionar, puede establecer una marca en FOCUS, leerla desde MOUSEUP y restablecerla para que los eventos futuros de MOUSEUP funcionen como se esperaba.

$("#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);
});
ThiagoPXP
fuente
1

Si bien esto funciona para seleccionarlo en IE, Firefox, Chrome, Safari y Opera, no le permitirá editarlo haciendo clic por segunda vez en Firefox, Chrome y Safari. No del todo seguro, pero creo que esto puede deberse a que esos 3 navegadores vuelven a emitir un evento de enfoque a pesar de que el campo ya tiene el enfoque, por lo que nunca le permite insertar el cursor (ya que lo está seleccionando nuevamente), mientras que en IE y Opera parece que no está haciendo eso, por lo que el evento de enfoque no se disparó nuevamente y, por lo tanto, el cursor se inserta.

Encontré una mejor solución en esta publicación de Stack que no tiene ese problema y funciona en todos los navegadores.

emprendedor
fuente
1

Esto debería funcionar también en Chrome:

$("#souper_fancy").focus(function() {
    var tempSouper = $(this);
    setTimeout(function(){
        tempSouper.select();
    },100);
});
rubiwachs
fuente
Considere agregar comentarios constructivos sobre por qué OP ve el problema y su solución lo soluciona.
Mirko Adari
1

Debido a que hay parpadeo cuando usa setTimeout, hay otra solución basada en eventos. De esta manera, el evento 'focus' adjunta el evento 'mouseup' y el controlador de eventos se desconecta nuevamente.

    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);
}

Luego cablee el primer evento

    $('.varquantity').on('focus', selectAllOnFocus);
usuario2941872
fuente
1

Usar setSelectionRange()dentro de una devolución de llamada para 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;
    });
});

Usar en setSelectionRange()lugar de select()ya select()que no funciona en Safari móvil (consulte Seleccionar texto mediante programación en un campo de entrada en dispositivos iOS (Safari móvil) ).

Es necesario esperar a usar requestAnimationFrameantes de seleccionar el texto; de lo contrario, el elemento no se desplazará correctamente a la vista después de que aparezca el teclado en iOS.

Al usarlo setSelectionRange(), es importante establecer el tipo de entrada en text, de lo contrario, puede generar excepciones en Chrome (consulte selectionStart / selectionEnd en input type = "number" ya no se permite en Chrome ).

andrewh
fuente
0

Si alguien se encuentra nuevamente con este problema, obtuve aquí una solución JS pura que (en este momento) funciona en todos los navegadores, incl. móvil

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

(sin setTimeout () no funciona en Safari, Safari móvil y MS Edge)

Claudio
fuente