Detectando o preenchimento automático do navegador

165

Como saber se um navegador preencheu automaticamente uma caixa de texto? Especialmente com caixas de nome de usuário e senha que são preenchidas automaticamente em torno do 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 queira impedir que isso ocorra, basta conectar-se ao evento. De preferência algo como isto:

if (autoFilled == true) {

} else {

}

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

Possíveis duplicatas

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

Eventos acionados pelo preenchimento automático do navegador e Javascript

- Essas perguntas não explicam realmente quais eventos são acionados, mas apenas reaproximam continuamente a caixa de texto (não é bom para o desempenho!).

Indefinido
fonte
1
A verificação leva alguns microssegundos, enquanto o intervalo dispara a verificação a cada 100 milissegundos mais ou menos ... como isso afetará o desempenho? Se houvesse um evento disparado pelo navegador, tenho certeza de que eles o teriam usado.
Esailija 29/07
Eu vejo o que você quer dizer, mas isso depende da primeira parte da minha pergunta se o JavaScript é ainda a mudança de uma consciência acaba de ter lugar (por exemplo, antes document.ready)
Undefined
1
A melhor solução para o Chrome / WebKit é usar o seletor DOM: document.querySelectorAll ('input: -webkit-autofill'); após um pequeno atraso setTimeout (... codifique aqui ... 250);
ChrisN
Basicamente, eu quero fazer o login automático do usuário, se for preenchido automaticamente, é irritante e louco para logar novamente quando ele sair automaticamente.
Muhammad Umer 22/11
@ ChrisN Seu comentário é o que realmente me deu uma solução (simples). Eu não vejo isso como uma resposta! Publique como um e faça ping para mim, para que eu possa votar novamente em agradecimento.
precisa saber é o seguinte

Respostas:

123

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 conectar-se a um evento que é acionado quando o navegador preenche automaticamente um campo de entrada.

  • Altere o acionador de eventos para diferentes navegadores:

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

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

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

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

Para sua pergunta sobre se é preenchido no documento ou antes dele, novamente ele varia de navegador para navegador e de versão para versão. Para campos de nome de usuário / senha apenas quando você seleciona um campo de senha de nome de usuário é preenchido. Portanto, você teria um código muito confuso se tentar se conectar a qualquer evento.

Você pode ter uma boa leitura sobre isso AQUI

afrin216
fonte
26
Observe que há uma diferença entre o preenchimento automático e o preenchimento automático. O OP refere-se especificamente aos navegadores que preenchem os detalhes de login salvos no carregamento da página.
Robbert
2
Um hack comum é um mousenter em alguma parte importante da página. O evento é acionado quando o mouse do usuário dirige-se para o botão ou algo parecido.
Bryce
1
@Bryce Pessoalmente, eu iria com um evento 'blur' devido ao preenchimento automático ser algo que acontece depois que você entra na área de entrada. Obviamente não é o ideal, mas como uma alternativa para os navegadores listados acima, pode ser muito útil
JakeJ
Não esqueça o inputevento. É isso que o Chrome aciona no preenchimento automático (e provavelmente também no preenchimento automático, se o Chrome tiver isso; eu sempre desativo isso).
TJ Crowder
Veja minha resposta em uma linha, se você quiser saber se o valor na caixa de texto foi preenchido pelo preenchimento automático do google chrome.
ThdK
70

Solução para navegadores WebKit

Nos documentos MDN da pseudo-classe CSS -webkit-autofill CSS:

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

Podemos definir uma regra css de transição nula no <input>elemento desejado , uma vez :-webkit-autofilleditado. JS será capaz de se conectar ao animationstartevento.

Créditos à equipe da interface do usuário Klarna . Veja sua boa implementação aqui:

Lev Kazakov
fonte
1
Esta é, de longe, a melhor solução! Parabéns ao Lev aqui por isso. Obrigado por compartilhar a solução da Klarna UI ... nada mais funcionou para mim até que eu encontrei isso. Economizador de vida!
Braden Rockwell Napier
1
Bem como o CSS governa os keyframes aqui github.com/klarna/ui/blob/v4.10.0/Field/styles.scss#L181-L189 também são necessários
user1069816
Isso funcionou perfeitamente para mim! Precisa brincar um pouco para descobrir a abordagem exata. Obrigado equipe Klarna
pritesh
18

Isso funciona para mim nas versões mais recentes do Firefox, Chrome e Edge:

$('#email').on('blur input', function() {
    ....
});
James
fonte
6
'input'! Essa foi a solução mais fácil para mim, mas testei apenas para o preenchimento automático, não para o preenchimento automático.
GreenRaccoon23
desfocagem não funciona para mim com alguma auto completa add-ons
pathfinder
A entrada será acionada a cada pressionamento de tecla. Se você fizer uma chamada de servidor, ela poderá ser acionada com frequência.
RiZKiT
Ótima solução! Essa combinação de eventos resolve o problema de preenchimento pelo usuário e preenchimento automático pelo navegador.
Petr Hladík
17

Para o preenchimento automático do google chrome, funcionou para mim:

if ($("#textbox").is(":-webkit-autofill")) 
{    
    // the value in the input field of the form was filled in with google chrome autocomplete
}
ThdK
fonte
Funcionou para mim também. Eu tentei centenas de soluções e ninguém funcionou. Muito obrigado, salve o meu dia e todas as vezes que procurei uma solução.
Perozzo 6/07
4
este erro abordagem trows: "Erro de sintaxe, a expressão não reconhecida: pseudo sem suporte: -webkit-preenchimento automático" em outros navegadores (eu tentei no Firefox)
anvita Surapaneni
1
Não está funcionando no chrome, assim como em 2020, também gera uma expressão não reconhecida de erro: pseudo não suportado: -webkit-autofill
Leo
15

Caso alguém esteja procurando uma solução (como eu estava hoje), para ouvir uma alteração de preenchimento automático do navegador, aqui está um método jquery personalizado que eu construí, apenas para simplificar o processo ao adicionar um ouvinte de alteração a uma 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);
    };

Você pode chamar assim:

$("#myInput").allchange(function () {
    alert("change!");
});
LcSalazar
fonte
1
Por alguma razão, para mim, esse código não está funcionando no redirecionamento de página (quando eu saio do aplicativo e sou redirecionado para a página de login onde o preenchimento automático acontece). Embora funcione na atualização da página.
VishwaKumar
1
que se parece bastante com o escorredor de bateria móvel: /
Stefan Fisk
@ StefanFisk - Na verdade, não. Um simples timer de repetição definido no nível JS de uma página do navegador não é suficiente para impactar sua bateria, pois há muita coisa acontecendo na maioria das páginas da web ... Você realmente acha que o google.com não define temporizadores recorrentes? O que uma falha de gerenciamento de energia que seria se eu poderia programar simplesmente com JS uma página web que drena a bateria de um usuário ....
LcSalazar
15

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

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

onde inputBackgroundNormalStatepara o meu modelo é 'rgb (255, 255, 255)'.

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

Editar: isso funciona para todos os navegadores

DrNio
fonte
Ótimo pensamento!
o moto
7

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

  • Pesquisa a cada meio a terço de segundo (na maioria dos casos, não precisa ser instantâneo)
  • Acione o evento de mudança usando JQuery e faça sua lógica em uma função que está ouvindo o evento de mudança.
  • Adicione uma correção para os valores ocultos da senha do preenchimento automático 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);
    });
Balde
fonte
6

Há um novo componente polyfill para resolver esse problema no github. Dê uma olhada no evento de preenchimento automático . Basta instalar o bower e pronto, o preenchimento automático funciona conforme o esperado.

bower install autofill-event
David
fonte
Isso funcionou muito bem com os formulários personalizados jQuery. Acabei de inseri-lo e minhas listas de seleção personalizadas funcionaram muito bem com o preenchimento automático.
Chris Bloom
6

Minha solução:

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

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

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

Camilo Martin
fonte
Perfeito. A primeira solução que encontrei ao trabalhar com o Chrome!
Rid Iculous
3
É realmente @RidIculous a simplicidade de algumas soluções.
Camilo Martin
3
Mas elem.val () retorna uma string vazia para campos de senha preenchidos automaticamente no chrome :(
Hemant_Negi 16/07/2015
@Hemant_Negi O Chrome não envia o evento de mudança? Corrija-me se eu estiver errado. Estou usando o LastPass e tenho preguiça de desabilitá-lo para ver se ele também funciona sem ele.
Camilo Martin
1
Sim, evento de alteração de despacho do cromo, mas, quando tento recuperar o valor, ele retorna vazio.
Hemant_Negi 27/07/2015
4

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

input:-webkit-autofill ~ label {
    top:-20px;
} 
st0495
fonte
Isso é útil.
Rustyshackleford # 9/19
Exatamente o que eu precisava :)
Dabrule 12/06
4

Eu estava procurando uma coisa semelhante. Somente Chrome ... No meu caso, a div do wrapper precisava saber se o campo de entrada foi preenchido automaticamente. Então, eu poderia fornecer CSS extra, assim como o Chrome faz no campo de entrada quando o preenche automaticamente. Ao analisar 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

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

Eu sei que esse é um tópico antigo, mas posso imaginar que muitos venham a encontrar uma solução para isso aqui.

Para fazer isso, você pode verificar se as entradas têm valores com:

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

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

S.Lund
fonte
1
Este código funciona muito bem para mim se você atualizar a terceira linha para($("#inputID:-webkit-autofill").val().length > 0) {
Hector
3

Esta é a solução para navegadores com o mecanismo de renderização do webkit . Quando o formulário é preenchido automaticamente, as entradas receberão a pseudo classe : -webkit-autofill- (por exemplo, entrada: -webkit-autofill {...}). Portanto, esse é o identificador que você deve verificar via JavaScript.

Solução com alguma forma de teste:

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

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

});

O problema quando a página é carregada é obter o valor da senha, mesmo o tamanho. Isso ocorre porque a segurança do navegador. Também o tempo limite é porque o navegador preencherá o formulário após alguma sequência de tempo.

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

Adam Šipický
fonte
Esta é a resposta atualizada.
Ben Racicot
Eu tentei esta solução e funcionou muito bem para mim. Muito obrigado.
Marcus Crisostomo
2

Eu tenho a solução perfeita para esta pergunta, tente este trecho de código.
A demonstração 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;
}
<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
fonte
2

No chrome, você pode detectar campos de preenchimento automático definindo uma regra css especial para elementos preenchidos automaticamente e, em seguida, verificando com javascript se o elemento tem 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"))
Pietro Coelho
fonte
2

Aqui está a solução CSS retirada da equipe da Klarna UI. Veja sua boa implementação aqui, recurso

Funciona bem para mim.

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

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

O código HTML deve mudar para este:

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

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

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

Usei o evento de desfoque no nome de usuário para verificar se o campo pwd havia sido 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 (verifiquei apenas o IE)

Bridget Arrington
fonte
@ Chrishr Eu testei minha solução com o IE, os navegadores lidam com os eventos javascsript de maneira diferente. Minha solução é simples e fácil de ler e é para um dos navegadores mais difíceis de codificar.
Bridget Arrington
1
Acabo com a mesma solução: blurevent. I aplicar a mesma função para o changee blurevento e funcionou muito bem. Uma solução simples sem bibliotecas extras.
Paulo Check
0

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

Ele inicia a pesquisa em todos os campos de entrada quando a página está carregando (eu configurei 10 segundos, mas você pode ajustar esse valor).
Após 10 segundos, ele interrompe a pesquisa em todos os campos de entrada e começa a pesquisar apenas na entrada focada (se houver). Para quando você desfoca a entrada e inicia novamente se você focalizar uma.

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

Não funciona muito bem quando você tem vários valores inseridos automaticamente, mas pode ser ajustado procurando todas as entradas 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);
});
Fez Vrasta
fonte
0

Se você deseja detectar apenas se o preenchimento automático foi usado ou não, em vez de detectar exatamente quando e para qual campo o preenchimento automático foi usado, basta adicionar um elemento oculto que será preenchido automaticamente e verificar se isso contém qualquer valor. Entendo que talvez não seja isso o que muitas pessoas estão interessadas. Defina o campo de entrada com um tabIndex negativo e com coordenadas absolutas bem fora da tela. É importante que a entrada faça parte da mesma forma que o restante da entrada. Você deve usar um nome que será escolhido pelo preenchimento automático (por exemplo, "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 entrada ao formulário e verifique seu valor no envio do formulário.

bornSwift
fonte
0

não parece ser uma solução para este que não depende de votação (pelo menos para o Chrome). É quase tão idiota, mas acho que é marginalmente melhor que a pesquisa global.

Considere o seguinte cenário:

  1. O usuário começa a preencher o campo1

  2. O usuário seleciona uma sugestão de preenchimento automático que preenche automaticamente os campos 2 e 3

Solução: registre um onblur em todos os campos que verifique a presença de campos preenchidos automaticamente por meio do seguinte snippet do jQuery $ (': - webkit-autofill')

Isso não será imediato, pois será adiado até que o usuário desfoque o campo1, mas não depende da pesquisa global, portanto, o IMO é uma solução melhor.

Dito isto, como pressionar 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')

Dan D
fonte
0

Pela minha experiência pessoal, o código abaixo funciona bem com o firefox IE e 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 entrada e, a partir daí, você poderá verificar se o campo de entrada está vazio ou não.

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

Eu consegui no chrome com:

    setTimeout(
       function(){
          $("#input_password").focus();
          $("#input_username").focus();
          console.log($("#input_username").val());
          console.log($("#input_password").val());
       }
    ,500);
Antoine O
fonte
Não tenho certeza de quando exatamente o preenchimento automático do Chrome é executado, mas em $ ('input, select'). On ('focusin', function (evt) {...}); Já recebo valores preenchidos automaticamente para todos os campos.
mirek 15/07
Nova versão, talvez?
Antoine O
0

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');
          }
      );
  });
Romick
fonte
Uma explicação para a sua solução ajudaria
ton
Eu pensei que era obviamente. Então, basicamente, a idéia é verificar o valor do campo de entrada algumas vezes. Na implementação atual, é 10 vezes com atraso de 100 ms. Portanto, quando, durante um segundo navegador de 10 * 1000 = 1s, preencher o valor de preenchimento automático, será chamado o retorno de chamada passado para o preenchimento automático. No exemplo atual, apenas adiciona uma classe. Se você tiver mais perguntas, não hesite e pergunte :).
Romick
0

Após a pesquisa, o problema é que os navegadores da Webkit não acionam evento de alteração no preenchimento automático. Minha solução foi obter a classe de preenchimento automático que o webkit adiciona e acionar 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

Cvetan Himchev
fonte
0

Para detectar e-mail, por exemplo, tentei "em mudança" e um observador de mutações, nem funcionou. O setInterval funciona bem com o preenchimento automático do LinkedIn (não revelando todo o meu código, mas você entendeu a idéia) e funciona bem com o back-end se você adicionar condições extras aqui para desacelerar o AJAX. E se não houver alterações no campo do formulário, como se não estivessem digitando para editar seus emails, o lastEmail evitará pings inúteis do AJAX.

// 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
fonte
0

Eu tive dificuldade em detectar o preenchimento automático no Firefox. Esta é a única solução que funcionou para mim:

Demo

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 o Chrome, eu uso: if ($(this).css('animation-name') == 'onAutoFillStart')

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

Serj
fonte
-2

tente em CSS

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

schwarzkopf
fonte