mostrar - habilitar javascript en chrome en windows
Detectando Autocompletar del navegador (23)
¿Cómo se puede saber si un navegador ha llenado automáticamente un cuadro de texto? Especialmente con los cuadros de nombre de usuario y contraseña que se autocompletan 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? ¿Está 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 mostrando tu respuesta.
Posibles duplicados
¿Evento DOM para autocompletar contraseña del navegador?
Eventos desencadenados por Autocompletar y JavaScript del navegador
- Ambas preguntas realmente no explican qué eventos se desencadenan, solo vuelven a comprobar continuamente el cuadro de texto (¡no es bueno para el rendimiento!).
Solución para navegadores WebKit
De los documentos de MDN para la pseudoclase CSS de : -webkit-autofill :
La pseudoclase 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 elemento <input>
deseado una vez que esté :-webkit-autofill
ed. JS luego podrá conectar el evento animationstart
.
Créditos para el equipo UI de Klarna . Vea su buena implementación aquí:
Desde mi experiencia personal, el siguiente código funciona bien con Firefox IE y Safari, pero no funciona muy bien al elegir 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();
});
Después de investigar, el problema es que los navegadores webkit no activan el evento de cambio en autocompletar. Mi solución fue obtener la clase de autocompletar que Webkit agrega y activar el evento de cambio por mi cuenta.
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
El problema es que el autocompletado se maneja de forma 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 desencadena cuando el navegador completa automáticamente un campo de entrada.
Cambiar desencadenador de evento para diferentes navegadores:
Para campos de nombre de usuario / contraseña:
- Firefox 4, IE 7 e IE 8 no envían el evento de cambio.
- Safari 5 y Chrome 9 envían el evento de cambio.
Para otros campos de formulario:
- IE 7 e IE 8 no envían el evento de cambio.
- Firefox 4 distribuye el evento de cambio de cambio cuando los usuarios seleccionan un valor de una lista de sugerencias y tabulan fuera del campo.
- Chrome 9 no distribuye el evento de cambio.
- Safari 5 envía el evento de cambio.
Las mejores opciones son deshabilitar la función de autocompletar para un formulario usando autocomplete="off"
en su formulario o sondear a intervalos regulares para ver si está lleno.
Para su pregunta sobre si se completa en o antes de que se vuelva a preparar el documento, varía de navegador a navegador e incluso de versión a versión. Para campos de nombre de usuario / contraseña, solo cuando se selecciona un campo de contraseña de usuario se completa. Entonces, en conjunto, tendrías un código muy desordenado si intentas unirte a cualquier evento.
Puedes leer bien HERE
En Chrome, puede detectar campos de autocompletar por configuración una regla CSS especial para elementos autocompletados, y luego verificar con javascript si el elemento tiene aplicada esa regla.
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"))
En caso de que alguien esté buscando una solución (como lo era hoy), para escuchar un cambio de autocompletar del 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!");
});
Esta es una solución para navegadores con motor de renderizado webkit . Cuando el formulario se rellena automáticamente, las entradas obtendrán pseudoclase: -webkit-autofill- (fe input: -webkit-autofill {...}). Este es el identificador de lo 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 es porque 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 completadas. Además, traté de verificar el valor o la duración de la contraseña del tipo de entrada, 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!
Esto funciona para mí en los últimos Firefox, Chrome y Edge:
$(''#email'').on(''blur input'', function() {
....
});
Hay un nuevo componente de relleno para solucionar este problema en github. Eche un vistazo a autofill-event . Solo necesita instalarlo y, listo, completar automáticamente funciona como se esperaba.
bower install autofill-event
Lamentablemente, la única manera confiable que he encontrado para verificar este navegador cruzado es sondear la entrada. Para que sea receptivo, también escucha los eventos. Chrome ha comenzado a ocultar los valores de autocompletar de javascript que necesita un hack.
- Encuesta cada medio a un tercio de segundo (No necesita ser instantáneo en la mayoría de los casos)
- Dispare el evento de cambio usando JQuery luego haga su lógica en una función escuchando el evento de cambio.
Agregue una solución para los valores ocultos de contraseña de autocompletar 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); });
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'');
}
);
});
Mi solución:
Escuche para change
eventos 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 disparará los eventos de cambio para todos los campos que no están vacíos antes de que el usuario tenga la oportunidad de editarlos.
Para autocompletar 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
}
Parece que hay una solución para esto que no depende de las encuestas (al menos para Chrome). Es casi tan hackish, pero creo que es marginalmente mejor que las encuestas globales.
Considere la siguiente situación:
El usuario comienza a completar el campo1
El usuario selecciona una sugerencia de autocompletar que autocompleta el campo2 y el campo3
Solución: registre un onblur en todos los campos que verifiquen la presencia de campos rellenos automáticamente mediante el siguiente jQuery snippet $ ('': - webkit-autofill'')
Esto no será inmediato, ya que se retrasará hasta que el usuario desenfoque el campo1, pero no confíe en el sondeo global, por lo que IMO, es una solución mejor.
Dicho esto, dado que presionar la tecla enter puede enviar un formulario, también puede necesitar un controlador correspondiente para onkeypress.
Alternativamente, puede usar sondeo global para verificar $ ('': - webkit-autofill'')
Sé que este es un hilo viejo, pero me puedo imaginar que muchos vienen a encontrar una solución para esto aquí.
Para hacer esto, puede verificar si la (s) entrada (s) tiene (n) valor (es) con:
$(function() {
setTimeout(function() {
if ($("#inputID").val().length > 0) {
// YOUR CODE
}
}, 100);
});
Lo utilizo yo mismo para verificar los valores en mi formulario de inicio de sesión cuando se carga para habilitar el botón Enviar. El código está hecho para jQuery pero es fácil de cambiar si es necesario.
Si solo desea detectar si se ha utilizado o no el autocompletado, en lugar de detectar exactamente cuándo y a qué campo se ha utilizado el autocompletado, simplemente puede agregar un elemento oculto que se completará automáticamente y luego verificar si contiene cualquier valor Entiendo que esto puede no ser lo que le interesa a mucha gente. Establezca el campo de entrada con un tabIndex negativo y con las 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á recogido 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 en el formulario enviado.
También me enfrenté al 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;
}
Tengo la solución perfecta para esta pregunta, pruebe este fragmento de código.
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>
Tuve éxito en Chrome con:
setTimeout(
function(){
$("#input_password").focus();
$("#input_username").focus();
console.log($("#input_username").val());
console.log($("#input_password").val());
}
,500);
Tuve el mismo problema y escribí esta solución.
Comienza a sondear en cada campo de entrada cuando la página se está cargando (he establecido 10 segundos pero puede ajustar este valor).
Después de 10 segundos, detiene el sondeo en cada campo de entrada y comienza a sondear solo en la entrada enfocada (si corresponde). Se detiene cuando difumina la entrada y nuevamente se inicia si enfoca uno.
De esta forma, sondeas solo cuando realmente lo necesites y solo con 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);
});
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'');
});
Utilicé el evento blur 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 marcado IE)
prueba en CSS
input:-webkit-autofill { border-color: #9B9FC4 !important; }