Rilevamento del riempimento automatico del browser


165

Come si fa a sapere se un browser ha riempito automaticamente una casella di testo? Soprattutto con le caselle nome utente e password che si riempiono automaticamente intorno al caricamento della pagina.

La mia prima domanda è quando si verifica ciò nella sequenza di caricamento della pagina? È prima o dopo document.ready?

In secondo luogo, come posso usare la logica per scoprire se ciò si è verificato? Non è che voglio impedire che ciò accada, basta agganciarsi all'evento. Preferibilmente qualcosa del genere:

if (autoFilled == true) {

} else {

}

Se possibile, mi piacerebbe vedere un jsfiddle che mostra la tua risposta.

Possibili duplicati

Evento DOM per il riempimento automatico della password del browser?

Riempimento automatico del browser ed eventi innescati Javascript

- Entrambe queste domande non spiegano davvero quali eventi vengono attivati, ma ricontrollano continuamente la casella di testo (non va bene per le prestazioni!).


1
Il controllo richiede alcuni microsecondi mentre l'intervallo genererebbe il controllo ogni 100 millisecondi circa ... in che modo ciò influirà sulle prestazioni? Se esistesse un evento generato dal browser, sono sicuro che l'avrebbero usato.
Esailija,

Capisco cosa intendi, ma dipende dalla prima parte della mia domanda se JavaScript sia persino consapevole che è appena avvenuta una modifica (ad es. Prima che document.ready)
Non definito il

1
LA MIGLIORE soluzione per Chrome / WebKit è usare il selettore DOM: document.querySelectorAll ('input: -webkit-autofill'); dopo un breve ritardo setTimeout (... codice qui ... 250);
ChrisN,

fondamentalmente voglio accedere automaticamente all'utente se è compilato automaticamente, pazzo o fastidioso o accedi di nuovo quando si disconnette automaticamente.
Muhammad Umer,

@ChrisN Il tuo commento è ciò che in realtà mi ha procurato una (semplice) soluzione. Non la vedo come una risposta, però! Pubblicalo come uno e eseguimi il ping, in modo da poterlo votare in ringraziamento.
Ethan Kaminski,

Risposte:


123

Il problema è che il riempimento automatico è gestito in modo diverso da diversi browser. Alcuni inviano l'evento change, altri no. Quindi è quasi impossibile collegarsi a un evento che viene attivato quando il browser completa automaticamente un campo di input.

  • Attivazione dell'evento di modifica per diversi browser:

    • Per i campi nome utente / password:

      1. Firefox 4, IE 7 e IE 8 non inviano l'evento change.
      2. Safari 5 e Chrome 9 inviano l'evento di modifica.
    • Per altri campi modulo:

      1. IE 7 e IE 8 non inviano l'evento change.
      2. Firefox 4 invia l'evento change change quando gli utenti selezionano un valore da un elenco di suggerimenti e una scheda fuori dal campo.
      3. Chrome 9 non invia l'evento di modifica.
      4. Safari 5 invia l'evento change.

Le opzioni migliori sono disabilitare il completamento automatico per un modulo utilizzando autocomplete="off" nel modulo o il sondaggio a intervalli regolari per vedere se è pieno.

Per la tua domanda se è compilato o prima del documento, già varia da browser a browser e persino da versione a versione. Per i campi nome utente / password solo quando si seleziona un campo password nome utente è pieno. Quindi nel complesso avresti un codice molto disordinato se provassi a collegarti a qualsiasi evento.

Puoi leggere bene questo qui QUI


26
Si noti che esiste una differenza tra il completamento automatico e il riempimento automatico. OP si riferisce specificamente ai browser che compilano i dettagli di accesso salvati al caricamento della pagina.
Robbert,

2
Un solito hack è un mousenter in una parte importante della pagina. L'evento viene attivato quando il mouse dell'utente punta sul pulsante o in altro modo.
Bryce,

1
@Bryce Personalmente andrei con un evento 'sfocato' perché il riempimento automatico è qualcosa che accade dopo che si entra nell'area di input. Ovviamente non è l'ideale ma come fallback per i browser sopra elencati può essere molto utile
JakeJ,

Non dimenticare l' inputevento. Questo è ciò che Chrome si attiva con il completamento automatico (e probabilmente anche con il riempimento automatico, se Chrome lo possiede; spengo sempre queste cose).
TJ Crowder,

Vedi la mia risposta a una riga se vuoi solo sapere se il valore nella casella di testo è stato compilato dal completamento automatico di Google Chrome.
Giovedì

72

Soluzione per browser WebKit

Dai documenti MDN per la pseudo-classe CSS : -webkit-autofill :

La pseudo-classe CSS: -webkit-autofill corrisponde quando un elemento ha il suo valore compilato automaticamente dal browser

Possiamo definire una regola CSS di transizione nulla <input>sull'elemento desiderato una volta che è stata modificata :-webkit-autofill. JS sarà quindi in grado di agganciarsi animationstartall'evento.

Crediti al team dell'interfaccia utente di Klarna . Guarda la loro bella implementazione qui:


1
questa è di gran lunga la soluzione migliore! Complimenti a Lev qui per questo. Grazie per aver condiviso la soluzione dell'interfaccia utente di Klarna ... nient'altro ha funzionato per me fino a quando non l'ho trovato. Salvavita!
Braden Rockwell Napier,

1
Oltre alle regole CSS sono necessari anche i fotogrammi chiave qui github.com/klarna/ui/blob/v4.10.0/Field/styles.scss#L181-L189
user1069816

Questo ha funzionato perfettamente per me! Deve giocarci un po 'per capire l'approccio esatto. Grazie squadra Klarna
pritesh

18

Questo funziona per me negli ultimi Firefox, Chrome e Edge:

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

6
'input'! Questa è stata la soluzione più semplice per me, ma ho testato solo il completamento automatico, non il riempimento automatico.
GreenRaccoon23,

la sfocatura non funziona con alcuni componenti aggiuntivi con completamento automatico
pathfinder,

L'input si attiverà ad ogni pressione del tasto. Se si effettua una chiamata al server, potrebbe attivarsi spesso.
RiZKiT

Ottima soluzione! Questa combinazione di eventi risolve il problema con riempimento per utente e riempimento automatico per browser.
Petr Hladík,

17

Per il completamento automatico di Google Chrome, questo ha funzionato per me:

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

Ha funzionato anche per me. Ho provato centinaia di soluzioni e nessuno ha funzionato. Grazie mille, salva la mia giornata e tutte le volte che ho cercato una soluzione.
Perozzo,

4
questo approccio genera l'errore: "Errore di sintassi, espressione non riconosciuta: pseudo non supportato: -webkit-autofill" su altri browser (ho provato su Firefox)
anvita surapaneni

1
Non funziona su Chrome oltre che sul 2020, genera anche espressioni non riconosciute di errore: pseudo non supportato: -webkit-autofill
Leo,

15

Nel caso in cui qualcuno stia cercando una soluzione (proprio come lo ero oggi), per ascoltare una modifica del riempimento automatico del browser, ecco un metodo jquery personalizzato che ho creato, solo per semplificare il processo quando si aggiunge un listener di modifica a un 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);
    };

Puoi chiamarlo così:

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

1
Per qualche motivo, questo codice non funziona sul reindirizzamento della pagina (quando esco dall'applicazione e vengo reindirizzato alla pagina di accesso in cui si verifica il riempimento automatico). Sebbene funzioni sull'aggiornamento della pagina.
VishwaKumar,

1
sembra proprio il dissipatore della batteria mobile: /
Stefan Fisk il

@StefanFisk - Non proprio così. Un semplice timer a ripetizione impostato a livello JS di una pagina del browser non è sufficiente per influire sulla batteria, poiché nella maggior parte delle pagine Web sta succedendo così tanto ... Pensi davvero che google.com non abbia timer ricorrenti? Che difetto di gestione dell'alimentazione sarebbe se potessi programmare semplicemente con JS una pagina web che scarica la batteria di un utente ....
LcSalazar

15

Stavo leggendo molto su questo problema e volevo fornire una soluzione molto rapida che mi ha aiutato.

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

dove inputBackgroundNormalState per il mio modello è 'rgb (255, 255, 255)'.

Quindi, fondamentalmente, quando i browser applicano il completamento automatico, tendono a indicare che l'input viene riempito automaticamente applicando un diverso (fastidioso) colore giallo sull'input.

Modifica: funziona per ogni browser


Ottimo pensiero!
moto

7

Sfortunatamente, l'unico modo affidabile che ho trovato per controllare questo browser incrociato è quello di eseguire il polling dell'input. Per renderlo reattivo, ascolta anche gli eventi. Chrome ha iniziato a nascondere i valori di riempimento automatico da JavaScript che necessita di un hack.

  • Esegui il polling ogni mezzo-terzo di secondo (nella maggior parte dei casi non deve essere istantaneo)
  • Attiva l'evento change usando JQuery, quindi esegui la tua logica in una funzione ascoltando l'evento change.
  • Aggiungi una correzione per i valori della password di compilazione automatica nascosti di 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);
    });

6

Esiste un nuovo componente polyfill per risolvere questo problema su github. Dai un'occhiata all'evento di compilazione automatica . Ho solo bisogno di installarlo e voilà, il riempimento automatico funziona come previsto.

bower install autofill-event

Funzionava perfettamente con i moduli personalizzati jQuery. L'ho appena inserito e i miei elenchi di selezione personalizzati hanno funzionato perfettamente con il riempimento automatico.
Chris Bloom,

6

La mia soluzione:

Ascolta gli changeeventi come faresti normalmente e, nel caricamento del contenuto DOM, procedi come segue:

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

Ciò genererà gli eventi di modifica per tutti i campi che non sono vuoti prima che l'utente abbia avuto la possibilità di modificarli.


Perfetto. La prima soluzione che ho trovato lavorando con Chrome!
Elimina Iculous il

3
È davvero @RidIculous quanto possano essere semplici alcune soluzioni.
Camilo Martin,

3
Ma elem.val () restituisce una stringa vuota per i campi password
compilati

@Hemant_Negi Chrome non invia comunque l'evento di modifica? Correggimi se sbaglio. Sto usando LastPass e sono troppo pigro per disabilitarlo per vedere se funziona anche senza.
Camilo Martin,

1
Sì, evento di modifica della spedizione di Chrome ma, quando provo a recuperare il valore, viene restituito vuoto.
Hemant_Negi,

4

Ho anche riscontrato lo stesso problema in cui l'etichetta non ha rilevato il riempimento automatico e l'animazione per lo spostamento dell'etichetta durante il riempimento del testo era sovrapposta e questa soluzione ha funzionato per me.

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

Questo è utile
Rustyshackleford,

Esattamente quello di cui avevo bisogno :)
Dabrule il

4

Stavo cercando una cosa simile. Solo Chrome ... Nel mio caso il div wrapper doveva sapere se il campo di input era compilato automaticamente. Quindi potrei dargli un extra CSS proprio come fa Chrome sul campo di input quando lo riempie automaticamente. Guardando tutte le risposte sopra la mia soluzione combinata era la seguente:

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

Il codice HTML per farlo funzionare sarebbe

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

3

So che questo è un vecchio thread, ma posso immaginare che molti vengano a trovare una soluzione qui.

Per fare ciò, è possibile verificare se gli input hanno valori con:

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

Lo uso da solo per verificare i valori nel mio modulo di accesso quando viene caricato per abilitare il pulsante di invio. Il codice è creato per jQuery ma è facile da modificare se necessario.


1
Questo codice funziona benissimo per me se aggiorni la terza riga a($("#inputID:-webkit-autofill").val().length > 0) {
Hector,

3

Questa è una soluzione per browser con motore di rendering webkit . Quando il modulo viene compilato automaticamente, gli input otterranno la pseudo classe : -webkit-autofill- (input fe: -webkit-autofill {...}). Quindi questo è l'identificatore che cosa devi controllare tramite JavaScript.

Soluzione con qualche modulo di prova:

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

});

Problema durante il caricamento della pagina è ottenere il valore della password, anche la lunghezza. Questo perché la sicurezza del browser. Anche il timeout , è perché il browser riempirà il modulo dopo una certa sequenza temporale.

Questo codice aggiungerà la classe auto_filled agli input riempiti. Inoltre, ho provato a controllare il valore della password del tipo di input o la lunghezza, ma ha funzionato subito dopo che si è verificato un evento nella pagina. Quindi ho provato ad attivare alcuni eventi, ma senza successo. Per ora questa è la mia soluzione. Godere!


Questa è la risposta aggiornata.
Ben Racicot,

Ho provato questa soluzione e ha funzionato molto bene per me. Grazie mille.
Marcus Crisostomo

2

Ho la soluzione perfetta per questa domanda, prova questo frammento di codice.
La demo è qui

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>


2

Su Chrome, puoi rilevare i campi di compilazione automatica impostando una regola CSS speciale per gli elementi compilati automaticamente, e quindi controllando con javascript se all'elemento è applicata quella regola.

Esempio:

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

2

Ecco la soluzione CSS presa dal team dell'interfaccia utente di Klarna. Guarda la loro bella implementazione qui risorsa

Funziona bene per me.

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

1

Ho usato questa soluzione per lo stesso problema.

Il codice HTML dovrebbe cambiare in questo:

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

e il codice jQuery dovrebbe essere in document.ready:

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

0

Ho usato l'evento blur sul nome utente per verificare se il campo pwd era stato compilato automaticamente.

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

Funziona con IE e dovrebbe funzionare con tutti gli altri browser (ho verificato solo IE)


@ChrisN Ho testato la mia soluzione con IE, i browser gestiscono gli eventi javascsript in modo diverso. La mia soluzione è semplice e facile da leggere ed è per uno dei browser più difficili da codificare.
Bridget Arrington,

1
Finisco con la stessa soluzione: blurevento. Applico la stessa funzione per l' changee blurmanifestazione e ha funzionato grande. Una soluzione semplice senza librerie extra.
Paulo Check,

0

Ho avuto lo stesso problema e ho scritto questa soluzione.

Inizia il polling su ogni campo di input durante il caricamento della pagina (ho impostato 10 secondi ma è possibile ottimizzare questo valore).
Dopo 10 secondi interrompe il polling su ogni campo di input e inizia il polling solo sull'input focalizzato (se presente). Si interrompe quando si sfoca l'ingresso e si avvia nuovamente se si mette a fuoco uno.

In questo modo si esegue il polling solo quando realmente necessario e solo su un input valido.

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

Non funziona abbastanza bene quando si inseriscono automaticamente più valori, ma potrebbe essere ottimizzato cercando ogni input nel modulo corrente.

Qualcosa di simile a:

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

0

Se vuoi solo rilevare se il riempimento automatico è stato usato o meno, piuttosto che rilevare esattamente quando e in quale campo è stato utilizzato il riempimento automatico, puoi semplicemente aggiungere un elemento nascosto che verrà riempito automaticamente e quindi verificare se questo contiene qualsiasi valore. Capisco che questo potrebbe non essere ciò che interessa a molte persone. Imposta il campo di input con una scheda negativa Index e con coordinate assolute ben al di fuori dello schermo. È importante che l'input faccia parte della stessa forma del resto dell'input. È necessario utilizzare un nome che verrà raccolto da Riempimento automatico (es. "Secondo nome").

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

Aggiungi questo input al modulo e verificane il valore al momento dell'invio del modulo.


0

ci fa sembra essere una soluzione a questo che non si basa su sondaggi (almeno per Chrome). È quasi altrettanto hacker, ma penso che sia leggermente migliore del polling globale.

Considera il seguente scenario:

  1. L'utente inizia a compilare il campo 1

  2. L'utente seleziona un suggerimento di completamento automatico che compila automaticamente field2 e field3

Soluzione: registrare un onblur su tutti i campi che verifica la presenza di campi compilati automaticamente tramite il seguente frammento jQuery $ (': - webkit-autofill')

Questo non sarà immediato poiché verrà ritardato fino a quando l'utente non sfuocerà field1 ma non si basa sul polling globale, quindi IMO, è una soluzione migliore.

Detto questo, poiché premendo il tasto Invio è possibile inviare un modulo, potrebbe essere necessario un gestore corrispondente per onkeypress.

In alternativa, puoi utilizzare il polling globale per controllare $ (': - webkit-autofill')


0

Dalla mia esperienza personale, il codice seguente funziona bene con Firefox IE e Safari, ma non funziona molto bene nella scelta del completamento automatico in Chrome.

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

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

Il codice sottostante funziona meglio, perché si attiverà ogni volta che l'utente fa clic sul campo di input e da lì puoi verificare che il campo di input sia vuoto o meno.

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

0

Sono riuscito su Chrome con:

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

Non sono sicuro quando si esegue esattamente il riempimento automatico di Chrome, ma in $ ('input, select'). On ('focusin', function (evt) {...}); Ricevo già valori compilati automaticamente per tutti i campi.
Mirek,

Nuova versione forse?
Antoine O

0

La mia soluzione è:

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

Una spiegazione per la tua soluzione sarebbe di aiuto
ton

Ho pensato che fosse ovviamente. Quindi in sostanza l'idea è quella di verificare il valore del campo di input un paio di volte. Nell'attuale implementazione sono 10 volte con un ritardo di 100 ms. Quindi quando durante un secondo browser 10 * 1000 = 1sec riempie il valore di riempimento automatico, verrà chiamato il callback passato al riempimento automatico. Nell'esempio corrente aggiunge solo una classe. Se hai altre domande, non esitare e chiedi semplicemente :).
Romick,

0

Dopo la ricerca, il problema è che i browser webkit non generano eventi di modifica al completamento automatico. La mia soluzione era quella di ottenere la classe di compilazione automatica che Webkit aggiunge e attivare l'evento di modifica da solo.

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

Ecco un link per il problema in cromo. https://bugs.chromium.org/p/chromium/issues/detail?id=636425


0

Per rilevare la posta elettronica, ad esempio, ho provato "al cambiamento" e un osservatore di mutazione, né ha funzionato. setInterval funziona bene con il riempimento automatico di LinkedIn (non rivelando tutto il mio codice, ma ottieni l'idea) e funziona bene con il backend se aggiungi ulteriori condizioni qui per rallentare AJAX. E se non ci sono cambiamenti nel campo del modulo, come se non stessero digitando per modificare la loro e-mail, l'ultima e-mail impedisce inutili ping 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

0

Ho avuto difficoltà a rilevare il riempimento automatico in Firefox. Questa è l'unica soluzione che ha funzionato per me:

dimostrazione

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

  }); 

Per Chrome utilizzo: if ($(this).css('animation-name') == 'onAutoFillStart')

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


-2

prova nei CSS

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.