Detectando o preenchimento automático do navegador

Como você sabe se um navegador preencheu automaticamente uma checkbox de texto? Especialmente com checkboxs de nome de usuário e senha que podem ser preenchidas automaticamente pelo carregamento da página.

Minha primeira pergunta é quando isso ocorre na sequência de carregamento da página? É antes ou depois do document.ready?

Em segundo lugar, como posso usar a lógica para descobrir se isso ocorreu? Não é que eu quero impedir que isso aconteça, basta ligar para o evento. De preferência algo como isto:

if (autoFilled == true) { } else { } 

Se possível, eu adoraria ver um jsfiddle mostrando sua resposta.

Possíveis duplicados

Evento DOM para preenchimento automático de senha do navegador?

Eventos desencadeados de preenchimento automático e JavaScript do navegador

– Ambas as perguntas não explicam realmente quais events são acionados, eles apenas reavaliam continuamente a checkbox de texto (não é bom para o desempenho!).

O problema é que o preenchimento automático é tratado de maneira diferente por diferentes navegadores. Alguns despacham o evento de mudança, outros não. Portanto, é quase impossível ligar a um evento que é acionado quando o navegador faz o preenchimento automático de um campo de input.

  • Alterar acionador de evento para diferentes navegadores:

    • Para campos de nome de usuário / senha:

      1. O Firefox 4, o IE 7 e o IE 8 não despacham o evento de mudança.
      2. O Safari 5 e o Chrome 9 despacham o evento de mudança.
    • Para outros campos de formulário:

      1. O IE 7 e o IE 8 não despacham o evento de mudança.
      2. O Firefox 4 despacha o evento de mudança quando os usuários selecionam um valor em uma lista de sugestões e saem do campo.
      3. O Chrome 9 não despacha o evento de alteração.
      4. O Safari 5 despacha o evento de mudança.

As melhores opções são desabilitar o preenchimento automático de um formulário usando autocomplete="off" no formulário ou pesquisar em intervalos regulares para ver se ele está preenchido.

Para sua pergunta sobre se é preenchida em ou antes de document.ready novamente, varia de navegador para navegador e até mesmo versão para versão. Para campos de nome de usuário / senha, somente quando você seleciona um campo de senha de nome de usuário é preenchido. Então, ao todo, você teria um código muito confuso se tentar append a qualquer evento.

Você pode ter uma boa leitura sobre isso aqui

Solução para navegadores WebKit

A partir dos documentos do MDN para a pseudo-class CSS -webkit-autofill :

A pseudo class CSS: -webkit-autofill corresponde quando um elemento tem seu valor preenchido automaticamente pelo navegador

Podemos definir uma regra css de transição nula no elemento desejado, uma vez que é :-webkit-autofill ed. O JS poderá, então, conectar-se ao evento de animationstart da animationstart .

Créditos para a equipe da UI da Klarna . Veja sua boa implementação aqui:

  • Regras CSS
  • Gancho JS

Apenas para o caso de alguém estar procurando uma solução (como eu era hoje), para ouvir uma alteração no preenchimento automático do navegador, aqui está um método jquery personalizado que eu criei, apenas para simplificar o processo ao adicionar um listener de alteração a uma input:

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

Você pode ligar assim:

 $("#myInput").allchange(function () { alert("change!"); }); 

Isso funciona para mim no mais recente Firefox, Chrome e Edge:

 $('#email').on('blur input', function() { .... }); 

Para o autocomplete do Google Chrome, isso funcionou para mim:

 if ($("#textbox").is(":-webkit-autofill")) { // the value in the input field of the form was filled in with google chrome autocomplete } 

Há um novo componente de polyfill para resolver esse problema no github. Dê uma olhada no evento de preenchimento automático . Só precisa de bower instalá-lo e voilà, autofill funciona como esperado.

 bower install autofill-event 

Infelizmente, a única maneira confiável que encontrei para verificar este navegador cruzado é pesquisar a input. Para torná-lo responsivo, também ouça os events. O Chrome começou a ocultar os valores de preenchimento automático do javascript, que precisam de um hack.

  • Poll a cada metade a um terço de segundo (não precisa ser instantâneo na maioria dos casos)
  • Acione o evento de mudança usando JQuery e faça sua lógica em uma function que esteja escutando o evento de mudança.
  • Adicione uma correção para os valores de senha de preenchimento automático ocultos do 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); }); 

Minha solução:

Ouça os events change como faria normalmente e, no carregamento do conteúdo DOM, faça o seguinte:

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

Isso acionará os events de mudança para todos os campos que não estão vazios antes que o usuário tenha a chance de editá-los.

Eu estava lendo muito sobre esse assunto e queria fornecer uma solução rápida que me ajudasse.

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

onde inputBackgroundNormalState para o meu modelo é ‘rgb (255, 255, 255)’.

Então, basicamente, quando os navegadores aplicam o preenchimento automático, eles tendem a indicar que a input é preenchida automaticamente aplicando uma cor amarela (irritante) diferente na input.

Edit: ele funcionará para cada navegador

Eu tenho a solução perfeita para esta pergunta, tente este trecho de código.
Demo está aqui

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

No chrome, você pode detectar campos de preenchimento automático por meio de uma regra especial de CSS para elementos preenchidos automaticamente e, em seguida, verificar com o javascript se o elemento tiver essa regra aplicada.

Exemplo:

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")) 

Eu sei que este é um segmento antigo, mas eu posso imaginar muitos vem para encontrar uma solução para isso aqui.

Para fazer isso, você pode verificar se a (s) input (s) possui (m) valor (es) com:

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

Eu uso isso para verificar os valores no meu formulário de login quando ele é carregado para ativar o botão de envio. O código é feito para o jQuery, mas é fácil de alterar, se necessário.

Eu usei essa solução para o mesmo problema.

O código HTML deve mudar para isso:

   

e o código jQuery deve estar em document.ready :

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

Também enfrentei o mesmo problema em que o label não detectou o preenchimento automático e a animação para mover o label no preenchimento do texto estava sobreposta e essa solução funcionou para mim.

 input:-webkit-autofill ~ label { top:-20px; } 

Eu estava procurando por algo semelhante. Somente Chrome … No meu caso, o wrapper div precisava saber se o campo de input estava preenchido automaticamente. Então, eu poderia dar um css extra, assim como o Chrome faz no campo de input quando o autofixa. Ao olhar todas as respostas acima, minha solução combinada foi a seguinte:

 /* * 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); 

O html para isso funcionar seria

 

Usei o evento blur no nome de usuário para verificar se o campo pwd estava preenchido automaticamente.

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

Isso funciona para o IE, e deve funcionar para todos os outros navegadores (eu só verifiquei o IE)

Eu tive o mesmo problema e escrevi esta solução.

Ele inicia a pesquisa em cada campo de input quando a página está carregando (defini 10 segundos, mas você pode ajustar esse valor).
Após 10 segundos, interrompe a pesquisa em todos os campos de input e inicia a pesquisa apenas na input focada (se houver). Ele pára quando você borrar a input e novamente começa se você focar um.

Desta forma, você pesquisa somente quando realmente necessário e somente em uma input 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); }); 

Não funciona muito bem quando você tem vários valores inseridos automaticamente, mas pode ser ajustado procurando cada input no formulário atual.

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

Se você quiser apenas detectar se o preenchimento automático foi usado ou não, em vez de detectar exatamente quando e em qual campo o preenchimento automático foi usado, basta adicionar um elemento oculto que será preenchido automaticamente e, em seguida, verificar se contém qualquer valor. Eu entendo que isso pode não ser o que muitas pessoas estão interessadas. Defina o campo de input com um tabIndex negativo e com coordenadas absolutas bem fora da canvas. É importante que a input faça parte da mesma forma que o restante da input. Você deve usar um nome que será escolhido pelo Auto-fill (ex. “Secondname”).

 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'; 

Anexe esta input ao formulário e verifique seu valor no envio do formulário.

Parece haver uma solução para isso que não depende de pesquisa (pelo menos para o Chrome). É quase tão agressivo, mas acho que é marginalmente melhor que a pesquisa global.

Considere o seguinte cenário:

  1. Usuário começa a preencher campo1

  2. O usuário seleciona uma sugestão de preenchimento automático que preenche automaticamente o campo2 e o campo3

Solução: Registre um onblur em todos os campos que verificam a presença de campos preenchidos automaticamente através do seguinte snippet $ (‘: – webkit-autofill’) do jQuery

Isso não será imediato, uma vez que será adiado até que o usuário desfaça o campo1, mas ele não depende de pesquisa global, então, IMO, é uma solução melhor.

Dito isto, desde que apertar a tecla enter pode enviar um formulário, você também pode precisar de um manipulador correspondente para onkeypress.

Como alternativa, você pode usar a pesquisa global para verificar $ (‘: – webkit-autofill’)

tente em CSS

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

Pela minha experiência pessoal, o código abaixo funciona bem com o IE do Firefox e com o Safari, mas não está funcionando muito bem ao escolher o preenchimento automático no Chrome.

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

O código abaixo funciona melhor, porque será acionado sempre que o usuário clicar no campo de input e, a partir daí, você pode verificar se o campo de input está vazio ou não.

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

Eu consegui no chrome com:

  setTimeout( function(){ $("#input_password").focus(); $("#input_username").focus(); console.log($("#input_username").val()); console.log($("#input_password").val()); } ,500); 

Minha solução é:

  $.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'); } ); }); 

Depois de pesquisar, o problema é que os navegadores webkit não ativam o evento de alteração no preenchimento automático. Minha solução foi obter a class de autopreenchimento que o webkit adiciona e aciona o evento de alteração sozinho.

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

Aqui está um link para o problema no cromo. https://bugs.chromium.org/p/chromium/issues/detail?id=636425

Esta é a solução para navegadores com o mecanismo de renderização do webkit . Quando o formulário é preenchido automaticamente, as inputs receberão uma class pseudo : -webkit-autofill- (fe input: -webkit-autofill {…}). Então, esse é o identificador que você deve verificar via JavaScript.

Solução com algum formulário de teste:

 

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

Problema quando a página carrega é obter o valor da senha, até o comprimento. Isso é porque a segurança do navegador. Além disso, o tempo limite é porque o navegador preencherá o formulário após algum tempo.

Este código adicionará a class auto_filled às inputs preenchidas. Além disso, tentei verificar o valor da senha do tipo de input, ou comprimento, mas funcionou logo após a ocorrência de algum evento na página. Então eu tentei acionar algum evento, mas sem sucesso. Por enquanto esta é a minha solução. Apreciar!