Detección de autocompletar navegador

165

¿Cómo saber si un navegador ha llenado automáticamente un cuadro de texto? Especialmente con cuadros de nombre de usuario y contraseña que se rellenan automáticamente alrededor de la carga de la página.

Mi primera pregunta es ¿cuándo ocurre esto en la secuencia de carga de la página? ¿Es antes o después de document.ready?

En segundo lugar, ¿cómo puedo usar la lógica para averiguar si esto ocurrió? No es que quiera evitar que esto ocurra, solo engancharme al evento. Preferiblemente algo como esto:

if (autoFilled == true) {

} else {

}

Si es posible, me encantaría ver un jsfiddle que muestre su respuesta.

Posibles duplicados

¿Evento DOM para autocompletar contraseña del navegador?

Autocompletado del navegador y eventos activados por Javascript

- Ambas preguntas no explican realmente qué eventos se activan, solo vuelven a verificar continuamente el cuadro de texto (¡no es bueno para el rendimiento!).

Indefinido
fuente
1
La verificación toma algunos microsegundos, mientras que el intervalo sería disparar la verificación cada 100 milisegundos más o menos ... ¿cómo afectará eso al rendimiento? Si existiera un evento activado por el navegador, estoy seguro de que lo habrían utilizado.
Esailija
Entiendo lo que quiere decir, pero depende de la primera parte de mi pregunta si JavaScript sabe que se ha producido un cambio (por ejemplo, antes de document.ready)
Indefinido
1
LA MEJOR solución para Chrome / WebKit es usar el selector DOM: document.querySelectorAll ('input: -webkit-autofill'); después de un breve retraso setTimeout (... código aquí ... 250);
ChrisN
Básicamente, quiero iniciar sesión automáticamente como usuario si se llena automáticamente, molesto o volver a iniciar sesión cuando cierra sesión automáticamente.
Muhammad Umer
@ChrisN Tu comentario es lo que realmente me dio una solución (simple). ¡Sin embargo, no lo veo como una respuesta! Publícalo como uno y hazme ping, para que pueda votarlo en agradecimiento.
Ethan Kaminski el

Respuestas:

123

El problema es que el autocompletado se maneja de manera diferente por diferentes navegadores. Algunos envían el evento de cambio, otros no. Por lo tanto, es casi imposible conectarse a un evento que se activa cuando el navegador completa automáticamente un campo de entrada.

  • Cambiar desencadenante de eventos para diferentes navegadores:

    • Para los campos de nombre de usuario / contraseña:

      1. Firefox 4, IE 7 e IE 8 no envían el evento de cambio.
      2. Safari 5 y Chrome 9 envían el evento de cambio.
    • Para otros campos de formulario:

      1. IE 7 e IE 8 no envían el evento de cambio.
      2. Firefox 4 distribuye el evento de cambio de cambio cuando los usuarios seleccionan un valor de una lista de sugerencias y pestañas fuera del campo.
      3. Chrome 9 no envía el evento de cambio.
      4. Safari 5 envía el evento de cambio.

Sus mejores opciones son desactivar el autocompletado para un formulario usando autocomplete="off" en su formulario o sondear a intervalos regulares para ver si está lleno.

Para su pregunta sobre si está lleno en o antes del documento, nuevamente varía de un navegador a otro e incluso de una versión a otra. Para los campos de nombre de usuario / contraseña solo cuando selecciona un campo de nombre de usuario y contraseña se completa Por lo tanto, tendrías un código muy desordenado si intentas adjuntarlo a cualquier evento.

Puedes leer bien aquí AQUÍ

afrin216
fuente
26
Tenga en cuenta que hay una diferencia entre autocompletar y autocompletar. OP se refiere específicamente a los navegadores que completan los detalles de inicio de sesión guardados en la carga de la página.
Robbert
2
Un truco habitual es un mousenter en alguna parte importante de la página. El evento se activa cuando el mouse del usuario se dirige al botón o algo similar.
Bryce
1
@Bryce Personalmente, iría con un evento de 'desenfoque' debido a que el autocompletado es algo que sucede después de que ingresas al área de entrada. Obviamente no es lo ideal, pero como alternativa para los navegadores mencionados anteriormente puede ser muy útil
JakeJ
No olvides el inputevento. Eso es lo que Chrome dispara en autocompletar (y probablemente también en autocompletar, si Chrome tiene eso; siempre apago esto).
TJ Crowder
Vea mi respuesta de una línea si solo desea saber si el valor en el cuadro de texto fue completado por autocompletado de Google Chrome.
ThdK
70

Solución para navegadores WebKit

De los documentos de MDN para la pseudo-clase CSS : -webkit-autofill :

La pseudo-clase CSS: -webkit-autofill coincide cuando un elemento tiene su valor autocompletado por el navegador

Podemos definir una regla CSS de transición nula en el <input>elemento deseado una vez que se :-webkit-autofilledita. JS podrá conectarse al animationstartevento.

Créditos al equipo de UI de Klarna . Vea su buena implementación aquí:

Lev Kazakov
fuente
1
¡Esta es, con diferencia, la mejor solución! Felicitaciones a Lev aquí por esto. Gracias por compartir la solución de Klarna UI ... nada más me ha funcionado hasta que encontré esto. Salvavidas!
Braden Rockwell Napier
1
Además de las reglas CSS, los fotogramas clave aquí github.com/klarna/ui/blob/v4.10.0/Field/styles.scss#L181-L189 también son necesarios
user1069816
¡Esto funcionó perfectamente para mí! Necesita jugar un poco con él para descubrir el enfoque exacto. Gracias equipo Klarna
pritesh
18

Esto funciona para mí en los últimos Firefox, Chrome y Edge:

$('#email').on('blur input', function() {
    ....
});
James
fuente
66
'input'! Esta fue la solución más fácil para mí, pero probé solo para autocompletar, no para autocompletar.
GreenRaccoon23
el desenfoque no funciona para mí con algunos complementos de autocompletado
pathfinder
La entrada se activará con cada pulsación de tecla. Si realiza una llamada al servidor, puede activarse con frecuencia.
RiZKiT
Gran solución! Esta combinación de eventos resuelve el problema con el llenado por usuario y el llenado automático por navegador.
Petr Hladík
17

Para el autocompletado de Google Chrome, esto funcionó para mí:

if ($("#textbox").is(":-webkit-autofill")) 
{    
    // the value in the input field of the form was filled in with google chrome autocomplete
}
ThdK
fuente
Funcionó para mí también. Probé cientos de soluciones y nadie funcionó. Muchas gracias, salva mi día y todas las veces que busqué una solución.
perozzo
44
este enfoque genera error: "Error de sintaxis, expresión no reconocida: pseudo no compatible: -webkit-autofill" en otros navegadores (probé en Firefox)
anvita surapaneni
1
No funciona en Chrome ni en 2020, también arroja una expresión de error no reconocida: pseudo no admitido: -webkit-autofill
Leo
15

En caso de que alguien esté buscando una solución (como lo estaba yo hoy), para escuchar el cambio de autocompletar de un navegador, aquí hay un método jquery personalizado que he creado, solo para simplificar el proceso al agregar un detector de cambios a una entrada:

    $.fn.allchange = function (callback) {
        var me = this;
        var last = "";
        var infunc = function () {
            var text = $(me).val();
            if (text != last) {
                last = text;
                callback();
            }
            setTimeout(infunc, 100);
        }
        setTimeout(infunc, 100);
    };

Puedes llamarlo así:

$("#myInput").allchange(function () {
    alert("change!");
});
LcSalazar
fuente
1
Por alguna razón para mí, este código no funciona en la redirección de la página (cuando cierro la sesión de la aplicación y me redirigen a la página de inicio de sesión donde ocurre el llenado automático). Aunque funciona en la página de actualización.
VishwaKumar
1
que parece bastante el dispositivo de descarga de la batería móvil: /
Stefan Fisk
@StefanFisk: en realidad no es así. Un simple temporizador de repetición configurado en el nivel JS de una página de navegador no es suficiente para afectar su batería, ya que hay mucho que hacer en la mayoría de las páginas web ... ¿Realmente cree que google.com no establece temporizadores recurrentes? Qué falla de administración de energía sería si pudiera programar simplemente con JS una página web que agote la batería de un usuario ...
LcSalazar
15

Estaba leyendo mucho sobre este problema y quería proporcionar una solución rápida que me ayudó.

let style = window.getComputedStyle(document.getElementById('email'))
  if (style && style.backgroundColor !== inputBackgroundNormalState) {
    this.inputAutofilledByBrowser = true
  }

dónde inputBackgroundNormalState para mi plantilla es 'rgb (255, 255, 255)'.

Básicamente, cuando los navegadores aplican el autocompletado, tienden a indicar que la entrada se completa automáticamente aplicando un color amarillo diferente (molesto) en la entrada.

Editar: esto funciona para todos los navegadores

DrNio
fuente
Gran pensamiento!
moto
7

Desafortunadamente, la única forma confiable que he encontrado para verificar este navegador cruzado es sondear la entrada. Para hacerlo receptivo, también escuche los eventos. Chrome ha comenzado a ocultar los valores de autocompletar de javascript que necesita un hack.

  • Encuesta cada medio a tercio de segundo (no necesita ser instantáneo en la mayoría de los casos)
  • Active el evento de cambio utilizando JQuery y luego haga su lógica en una función que escuche el evento de cambio.
  • Agregue una solución para los valores de contraseña de Autocompletar ocultos de Chrome.

    $(document).ready(function () {
        $('#inputID').change(YOURFUNCTIONNAME);
        $('#inputID').keypress(YOURFUNCTIONNAME);
        $('#inputID').keyup(YOURFUNCTIONNAME);
        $('#inputID').blur(YOURFUNCTIONNAME);
        $('#inputID').focusin(YOURFUNCTIONNAME);
        $('#inputID').focusout(YOURFUNCTIONNAME);
        $('#inputID').on('input', YOURFUNCTIONNAME);
        $('#inputID').on('textInput', YOURFUNCTIONNAME);
        $('#inputID').on('reset', YOURFUNCTIONNAME);
    
        window.setInterval(function() {
            var hasValue = $("#inputID").val().length > 0;//Normal
            if(!hasValue){
                hasValue = $("#inputID:-webkit-autofill").length > 0;//Chrome
            }
    
            if (hasValue) {
                $('#inputID').trigger('change');
            }
        }, 333);
    });
Cubeta
fuente
6

Hay un nuevo componente polyfill para abordar este problema en github. Echa un vistazo al evento de autocompletar . Solo necesito instalarlo y listo, el autocompletado funciona como se esperaba.

bower install autofill-event
David
fuente
Esto funcionó muy bien con jQuery Custom Forms. Lo dejé caer y mis listas de selección personalizadas funcionaron muy bien con el autocompletado.
Chris Bloom
6

Mi solución:

Escuche los changeeventos como lo haría normalmente, y en la carga de contenido DOM, haga esto:

setTimeout(function() {
    $('input').each(function() {
        var elem = $(this);
        if (elem.val()) elem.change();
    })
}, 250);

Esto activará los eventos de cambio para todos los campos que no estén vacíos antes de que el usuario tenga la oportunidad de editarlos.

Camilo Martin
fuente
Perfecto. ¡La primera solución que encontré trabajando con Chrome!
Rid Iculous
3
Es realmente @RidIculous lo simple que pueden ser algunas soluciones.
Camilo Martin
3
Pero elem.val () devuelve una cadena vacía para los campos de contraseña autocompletados en Chrome :(
Hemant_Negi
@Hemant_Negi ¿Chrome no envía el evento de cambio de todos modos? Corrígeme si me equivoco. Estoy usando LastPass y soy demasiado vago para deshabilitarlo para ver si también funciona sin él.
Camilo Martin
1
Sí, evento de cambio de despacho de Chrome, pero cuando intento recuperar el valor, vuelve vacío.
Hemant_Negi
4

También enfrenté el mismo problema en el que la etiqueta no detectaba el autocompletado y la animación para mover la etiqueta al llenar el texto se superponía y esta solución funcionó para mí.

input:-webkit-autofill ~ label {
    top:-20px;
} 
st0495
fuente
Esto es útil.
rustyshackleford
Exactamente lo que necesitaba :)
Dabrule
4

Estaba buscando algo similar. Solo Chrome ... En mi caso, la división del contenedor necesitaba saber si el campo de entrada se había completado automáticamente. Entonces podría darle CSS adicional al igual que Chrome hace en el campo de entrada cuando lo llena automáticamente. Al observar todas las respuestas anteriores, mi solución combinada fue la siguiente:

/* 
 * make a function to use it in multiple places
 */
var checkAutoFill = function(){
    $('input:-webkit-autofill').each(function(){
        $(this).closest('.input-wrapper').addClass('autofilled');
    });
}

/* 
 * Put it on the 'input' event 
 * (happens on every change in an input field)
 */
$('html').on('input', function() {
    $('.input-wrapper').removeClass('autofilled');
    checkAutoFill();
});

/*
 * trigger it also inside a timeOut event 
 * (happens after chrome auto-filled fields on page-load)
 */
setTimeout(function(){ 
    checkAutoFill();
}, 0);

El html para que esto funcione sería

<div class="input-wrapper">
    <input type="text" name="firstname">
</div>
Julesezaar
fuente
3

Sé que este es un hilo viejo pero puedo imaginar que muchos vienen a encontrar una solución a esto aquí.

Para hacer esto, puede verificar si las entradas tienen valores con:

$(function() {
    setTimeout(function() {
        if ($("#inputID").val().length > 0) {
            // YOUR CODE
        }
    }, 100);
});

Lo uso yo mismo para verificar los valores en mi formulario de inicio de sesión cuando se carga para habilitar el botón de envío. El código está hecho para jQuery pero es fácil de cambiar si es necesario.

S.Lund
fuente
1
Este código funciona muy bien para mí si actualiza la tercera línea a($("#inputID:-webkit-autofill").val().length > 0) {
Hector
3

Esta es una solución para navegadores con motor de renderizado webkit . Cuando el formulario se completa automáticamente, las entradas obtendrán una pseudo clase : -webkit-autofill- (entrada de fe: -webkit-autofill {...}). Así que este es el identificador que debe verificar a través de JavaScript.

Solución con alguna forma de prueba:

<form action="#" method="POST" class="js-filled_check">

    <fieldset>

        <label for="test_username">Test username:</label>
        <input type="text" id="test_username" name="test_username" value="">

        <label for="test_password">Test password:</label>
        <input type="password" id="test_password" name="test_password" value="">

        <button type="submit" name="test_submit">Test submit</button>

    </fieldset>

</form>

Y javascript:

$(document).ready(function() {

    setTimeout(function() {

        $(".js-filled_check input:not([type=submit])").each(function (i, element) {

            var el = $(this),
                autofilled = (el.is("*:-webkit-autofill")) ? el.addClass('auto_filled') : false;

            console.log("element: " + el.attr("id") + " // " + "autofilled: " + (el.is("*:-webkit-autofill")));

        });

    }, 200);

});

El problema cuando se carga la página es obtener el valor de la contraseña, incluso la longitud. Esto se debe a la seguridad del navegador. También el tiempo de espera , es porque el navegador completará el formulario después de una secuencia de tiempo.

Este código agregará la clase auto_filled a las entradas llenas. Además, intenté verificar el valor de la contraseña del tipo de entrada, o la longitud, pero funcionó justo después de que ocurriera algún evento en la página. Así que intenté desencadenar algún evento, pero sin éxito. Por ahora esta es mi solución. ¡Disfrutar!

Adam Šipický
fuente
Esta es la respuesta actualizada.
Ben Racicot
Probé esta solución y funcionó muy bien para mí. Muchas gracias.
Marcus Crisostomo el
2

Tengo la solución perfecta para esta pregunta, prueba este fragmento de código.
La demo está aquí

function ModernForm() {
    var modernInputElement = $('.js_modern_input');

    function recheckAllInput() {
        modernInputElement.each(function() {
            if ($(this).val() !== '') {
                $(this).parent().find('label').addClass('focus');
            }
        });
    }

    modernInputElement.on('click', function() {
        $(this).parent().find('label').addClass('focus');
    });
    modernInputElement.on('blur', function() {
        if ($(this).val() === '') {
            $(this).parent().find('label').removeClass('focus');
        } else {
            recheckAllInput();
        }
    });
}

ModernForm();
.form_sec {
  padding: 30px;
}
.form_sec .form_input_wrap {
  position: relative;
}
.form_sec .form_input_wrap label {
  position: absolute;
  top: 25px;
  left: 15px;
  font-size: 16px;
  font-weight: 600;
  z-index: 1;
  color: #333;
  -webkit-transition: all ease-in-out 0.35s;
  -moz-transition: all ease-in-out 0.35s;
  -ms-transition: all ease-in-out 0.35s;
  -o-transition: all ease-in-out 0.35s;
  transition: all ease-in-out 0.35s;
}
.form_sec .form_input_wrap label.focus {
  top: 5px;
  color: #a7a9ab;
  font-weight: 300;
  -webkit-transition: all ease-in-out 0.35s;
  -moz-transition: all ease-in-out 0.35s;
  -ms-transition: all ease-in-out 0.35s;
  -o-transition: all ease-in-out 0.35s;
  transition: all ease-in-out 0.35s;
}
.form_sec .form_input {
  width: 100%;
  font-size: 16px;
  font-weight: 600;
  color: #333;
  border: none;
  border-bottom: 2px solid #d3d4d5;
  padding: 30px 0 5px 0;
  outline: none;
}
.form_sec .form_input.err {
  border-bottom-color: #888;
}
.form_sec .cta_login {
  border: 1px solid #ec1940;
  border-radius: 2px;
  background-color: #ec1940;
  font-size: 14px;
  font-weight: 500;
  text-align: center;
  color: #ffffff;
  padding: 15px 40px;
  margin-top: 30px;
  display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<form class="form_sec">
    <div class="row clearfix">
        <div class="form-group col-lg-6 col-md-6 form_input_wrap">
            <label>
                Full Name
            </label>
            <input type="text" name="name" id="name" class="form_input js_modern_input">
        </div>
    </div>
    <div class="row clearfix">
        <div class="form-group form_input_wrap col-lg-6 col-md-6">
            <label>
                Emaill
            </label>
            <input type="email" name="email" class="form_input js_modern_input">
        </div>
    </div>
    <div class="row clearfix">
        <div class="form-group form_input_wrap col-lg-12 col-md-12">
            <label>
                Address Line 1
            </label>
            <input type="text" name="address" class="form_input js_modern_input">
        </div>
    </div>
    <div class="row clearfix">
        <div class="form-group col-lg-6 col-md-6 form_input_wrap">
            <label>
                City
            </label>
            <input type="text" name="city" class="form_input js_modern_input">
        </div>
        <div class="form-group col-lg-6 col-md-6 form_input_wrap">
            <label>
                State
            </label>
            <input type="text" name="state" class="form_input js_modern_input">
        </div>
    </div>
    <div class="row clearfix">
        <div class="form-group col-lg-6 col-md-6 form_input_wrap">
            <label>
                Country
            </label>
            <input type="text" name="country" class="form_input js_modern_input">
        </div>
        <div class="form-group col-lg-4 col-md-4 form_input_wrap">
            <label>
                Pin
            </label>
            <input type="text" name="pincode" class="form_input js_modern_input">
        </div>
    </div>
    <div class="row cta_sec">
        <div class="col-lg-12">
            <button type="submit" class="cta_login">Submit</button>
        </div>
    </div>
</form>

Suresh Pattu
fuente
2

En Chrome, puede detectar campos de autocompletar configurando una regla css especial para elementos autocompletados y luego verificando con javascript si el elemento tiene esa regla aplicada.

Ejemplo:

CSS

input:-webkit-autofill {
  -webkit-box-shadow: 0 0 0 30px white inset;
}

JavaScript

  let css = $("#selector").css("box-shadow")
  if (css.match(/inset/))
    console.log("autofilled:", $("#selector"))
Pietro Coelho
fuente
2

Aquí hay una solución CSS tomada del equipo de Klarna UI. Vea su implementación agradable aquí recurso

Funciona bien para mi.

input:-webkit-autofill {
  animation-name: onAutoFillStart;
  transition: background-color 50000s ease-in-out 0s;
}
input:not(:-webkit-autofill) {
  animation-name: onAutoFillCancel;
}
zdrsoft
fuente
1

Usé esta solución para el mismo problema.

El código HTML debería cambiar a esto:

<input type="text" name="username" />
<input type="text" name="password" id="txt_password" />

y el código jQuery debe estar en document.ready:

$('#txt_password').focus(function(){
    $(this).attr('type','password');
});
a828h
fuente
0

Utilicé el evento de desenfoque en el nombre de usuario para verificar si el campo pwd se había llenado automáticamente.

 $('#userNameTextBox').blur(function () {
        if ($('#userNameTextBox').val() == "") {
            $('#userNameTextBox').val("User Name");
        }
        if ($('#passwordTextBox').val() != "") {
            $('#passwordTextBoxClear').hide(); // textbox with "Password" text in it
            $('#passwordTextBox').show();
        }
    });

Esto funciona para IE, y debería funcionar para todos los demás navegadores (solo he comprobado IE)

Bridget Arrington
fuente
@ChrisN Probé mi solución con IE, los navegadores manejan los eventos javascsript de manera diferente. Mi solución es simple y fácil de leer y es para uno de los navegadores más difíciles de codificar.
Bridget Arrington
1
Termino con la misma solución: blurevento. Aplico la misma función para el changey blureventos y funcionó muy bien. Una solución simple sin bibliotecas adicionales.
Paulo Check
0

Tuve el mismo problema y escribí esta solución.

Comienza a sondear en cada campo de entrada cuando se carga la página (configuré 10 segundos pero puede ajustar este valor).
Después de 10 segundos, deja de sondear en cada campo de entrada y comienza a sondear solo en la entrada enfocada (si corresponde). Se detiene cuando difumina la entrada y vuelve a comenzar si enfoca uno.

De esta manera, solo sondea cuando realmente se necesita y solo en una entrada válida.

// This part of code will detect autofill when the page is loading (username and password inputs for example)
var loading = setInterval(function() {
    $("input").each(function() {
        if ($(this).val() !== $(this).attr("value")) {
            $(this).trigger("change");
        }
    });
}, 100);
// After 10 seconds we are quite sure all the needed inputs are autofilled then we can stop checking them
setTimeout(function() {
    clearInterval(loading);
}, 10000);
// Now we just listen on the focused inputs (because user can select from the autofill dropdown only when the input has focus)
var focused;
$(document)
.on("focus", "input", function() {
    var $this = $(this);
    focused = setInterval(function() {
        if ($this.val() !== $this.attr("value")) {
            $this.trigger("change");
        }
    }, 100);
})
.on("blur", "input", function() {
    clearInterval(focused);
});

No funciona bastante bien cuando tiene múltiples valores insertados automáticamente, pero podría modificarse buscando cada entrada en el formulario actual.

Algo como:

// This part of code will detect autofill when the page is loading (username and password inputs for example)
var loading = setInterval(function() {
    $("input").each(function() {
        if ($(this).val() !== $(this).attr("value")) {
            $(this).trigger("change");
        }
    });
}, 100);
// After 10 seconds we are quite sure all the needed inputs are autofilled then we can stop checking them
setTimeout(function() {
    clearInterval(loading);
}, 10000);
// Now we just listen on inputs of the focused form
var focused;
$(document)
.on("focus", "input", function() {
    var $inputs = $(this).parents("form").find("input");
    focused = setInterval(function() {
        $inputs.each(function() {
            if ($(this).val() !== $(this).attr("value")) {
                $(this).trigger("change");
            }
        });
    }, 100);
})
.on("blur", "input", function() {
    clearInterval(focused);
});
Fez Vrasta
fuente
0

Si solo desea detectar si se ha usado o no el autocompletado, en lugar de detectar exactamente cuándo y en qué campo se ha usado el autocompletado, simplemente puede agregar un elemento oculto que se llenará automáticamente y luego verificar si esto contiene cualquier valor Entiendo que esto puede no ser lo que le interesa a muchas personas. Establezca el campo de entrada con un índice negativo tab y con coordenadas absolutas fuera de la pantalla. Es importante que la entrada sea parte de la misma forma que el resto de la entrada. Debe usar un nombre que será seleccionado por Autocompletar (por ejemplo, "segundo nombre").

var autofilldetect = document.createElement('input');
autofilldetect.style.position = 'absolute';
autofilldetect.style.top = '-100em';
autofilldetect.style.left = '-100em';
autofilldetect.type = 'text';
autofilldetect.name = 'secondname';
autofilldetect.tabIndex = '-1';

Agregue esta entrada al formulario y verifique su valor al enviar el formulario.

bornSwift
fuente
0

No hace parece ser una solución a esto que no se base en el sondeo (al menos para Chrome). Es casi tan hostil, pero creo que es marginalmente mejor que las encuestas mundiales.

Considere el siguiente escenario:

  1. El usuario comienza a completar el campo 1

  2. El usuario selecciona una sugerencia de autocompletar que rellena automáticamente los campos 2 y 3

Solución: Registre un onblur en todos los campos que verifique la presencia de campos autocompletados a través del siguiente fragmento de jQuery $ (': - webkit-autofill')

Esto no será inmediato, ya que se retrasará hasta que el usuario difumine el campo1, pero no se basa en encuestas globales, por lo que, en mi opinión, es una mejor solución.

Dicho esto, dado que presionar la tecla Intro puede enviar un formulario, también puede necesitar un controlador correspondiente para onkeypress.

Alternativamente, puede usar el sondeo global para verificar $ (': - webkit-autofill')

Dan D
fuente
0

Desde mi experiencia personal, el siguiente código funciona bien con Firefox IE y Safari, pero no funciona muy bien en la selección de autocompletar en Chrome.

function check(){
clearTimeout(timeObj);
 timeObj = setTimeout(function(){
   if($('#email').val()){
    //do something
   }
 },1500);
}

$('#email').bind('focus change blur',function(){
 check();
});

El siguiente código funciona mejor, porque se activará cada vez que el usuario haga clic en el campo de entrada y desde allí puede verificar si el campo de entrada está vacío o no.

$('#email').bind('click', function(){
 check();
});
Roger
fuente
0

Tuve éxito en Chrome con:

    setTimeout(
       function(){
          $("#input_password").focus();
          $("#input_username").focus();
          console.log($("#input_username").val());
          console.log($("#input_password").val());
       }
    ,500);
Antoine O
fuente
No estoy seguro de cuándo se ejecuta exactamente el autocompletado de Chrome, pero en $ ('input, select'). On ('focusin', function (evt) {...}); Ya recibo valores autocompletados para todos los campos.
mirek
¿Nueva versión quizás?
Antoine O
0

Mi solución es:

    $.fn.onAutoFillEvent = function (callback) {
        var el = $(this),
            lastText = "",
            maxCheckCount = 10,
            checkCount = 0;

        (function infunc() {
            var text = el.val();

            if (text != lastText) {
                lastText = text;
                callback(el);
            }
            if (checkCount > maxCheckCount) {
                return false;
            }
            checkCount++;
            setTimeout(infunc, 100);
        }());
    };

  $(".group > input").each(function (i, element) {
      var el = $(element);

      el.onAutoFillEvent(
          function () {
              el.addClass('used');
          }
      );
  });
Romick
fuente
Una explicación para su solución ayudaría
ton
Pensé que era obviamente. Entonces, básicamente, la idea es verificar el valor del campo de entrada un par de veces. En la implementación actual es 10 veces con 100 ms de retraso. Entonces, cuando durante un segundo navegador de 10 * 1000 = 1 segundo llene el valor de autocompletar, se llamará a la devolución de llamada pasada a autocompletar. En el ejemplo actual, solo agrega una clase. Si tienes más preguntas, no lo dudes y solo pregunta :).
Romick
0

Después de la investigación, el problema es que los navegadores webkit no activan el evento de cambio en el autocompletado. Mi solución fue obtener la clase de autocompletar que agrega webkit y activar el evento de cambio por mí mismo.

setTimeout(function() {
 if($('input:-webkit-autofill').length > 0) {
   //do some stuff
 }
},300)

Aquí hay un enlace para el problema en cromo. https://bugs.chromium.org/p/chromium/issues/detail?id=636425

Cvetan Himchev
fuente
0

Para detectar el correo electrónico, por ejemplo, intenté "en cambio" y un observador de mutaciones, ninguno funcionó. setInterval funciona bien con el autocompletado de LinkedIn (no revela todo mi código, pero se entiende) y funciona bien con el backend si agrega condiciones adicionales aquí para ralentizar el AJAX. Y si no hay cambios en el campo del formulario, como si no estuvieran escribiendo para editar su correo electrónico, lastEmail evita los pings de AJAX sin sentido.

// lastEmail needs scope outside of setInterval for persistence.
var lastEmail = 'nobody';
window.setInterval(function() { // Auto-fill detection is hard.
    var theEmail = $("#email-input").val();
    if (
        ( theEmail.includes("@") ) &&
        ( theEmail != lastEmail )
    ) {
        lastEmail = theEmail;
        // Do some AJAX
    }
}, 1000); // Check the field every 1 second
PJ Brunet
fuente
0

Me costó mucho detectar el autocompletado en Firefox. Esta es la única solución que funcionó para mí:

Manifestación

HTML:

<div class="inputFields">
   <div class="f_o">
      <div class="field_set">
        <label class="phold">User</label>
        <input type="tel" class="form_field " autocomplete="off" value="" maxlength="50">
      </div>
   </div>
   <div class="f_o">
      <div class="field_set">
         <label class="phold">Password</label>
         <input type="password" class="form_field " autocomplete="off" value="" maxlength="50">
      </div>
   </div>
</div>

CSS:

/* Detect autofill for Chrome */
.inputFields input:-webkit-autofill {
    animation-name: onAutoFillStart;
    transition: background-color 50000s ease-in-out 0s;
}
.inputFields input:not(:-webkit-autofill) {
    animation-name: onAutoFillCancel;
}

@keyframes onAutoFillStart {
}

@keyframes onAutoFillCancel {
}
.inputFields {
  max-width: 414px;
}

.field_set .phold{
  display: inline-block;
  position: absolute;
  font-size: 14px;
  color: #848484;
  -webkit-transform: translate3d(0,8px,0);
  -ms-transform: translate3d(0,8px,0);
  transform: translate3d(0,8px,0);
  -webkit-transition: all 200ms ease-out;
  transition: all 200ms ease-out;
  background-color: transparent;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
  margin-left: 8px;
  z-index: 1;
  left: 0;
  pointer-events: none;
}

.field_set .phold_active {
   font-size: 12px;
   -webkit-transform: translate3d(0,-8px,0);
  -ms-transform: translate3d(0,-8px,0);
  transform: translate3d(0,-8px,0);
  background-color: #FFF;
  padding-left: 3px;
  padding-right: 3px;
}

.field_set input[type='text'], .field_set select, .field_set input[type='tel'], .field_set input[type='password'] {
    height: 36px;
}

.field_set input[type='text'], .field_set input[type='tel'], .field_set input[type='password'], .field_set select, .field_set textarea {
    box-sizing: border-box;
    width: 100%;
    padding: 5px;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    border: 1px solid #ababab;
    border-radius: 0;
}

.field_set {
    margin-bottom: 10px;
    position: relative;
}

.inputFields .f_o {
    width: 100%;
    line-height: 1.42857143;
    float: none;
}

JavaScript:

    // detect auto-fill when page is loading
  $(window).on('load', function() {
    // for sign in forms when the user name and password are filled by browser
    getAutofill('.inputFields');
  });

  function getAutofill(parentClass) {
    if ($(parentClass + ' .form_field').length > 0) {    
      var formInput = $(parentClass + ' .form_field');
      formInput.each(function(){   
        // for Chrome:  $(this).css('animation-name') == 'onAutoFillStart'
        // for Firefox: $(this).val() != ''
        if ($(this).css('animation-name') == 'onAutoFillStart' || $(this).val() != '') {
          $(this).siblings('.phold').addClass('phold_active');
        } else {
          $(this).siblings('.phold').removeClass('phold_active');
        }
      });
    }
  } 

  $(document).ready(function(){

    $(document).on('click','.phold',function(){
      $(this).siblings('input, textarea').focus();
    });
    $(document).on('focus','.form_field', function(){
      $(this).siblings('.phold').addClass('phold_active');
    });

    // blur for Chrome and change for Firefox
    $(document).on('blur change','.form_field', function(){
      var $this = $(this);
      if ($this.val().length == 0) {        
        $(this).siblings('.phold').removeClass('phold_active');
      } else {
        $(this).siblings('.phold').addClass('phold_active');
      }
    });

    // case when form is reloaded due to errors
    if ($('.form_field').length > 0) {
      var formInput = $('.form_field');
      formInput.each(function(){
        if ($(this).val() != '') {
          $(this).siblings('.phold').addClass('phold_active');
        } else {
          $(this).siblings('.phold').removeClass('phold_active');
        }
      });
    }

  }); 

Para Chrome uso: if ($(this).css('animation-name') == 'onAutoFillStart')

Para Firefox: if ($(this).val() != '')

Serj
fuente
-2

probar en CSS

input:-webkit-autofill { border-color: #9B9FC4 !important; }

Schwarzkopf
fuente