Automatisches Ausfüllen des Browsers erkennen

165

Wie können Sie feststellen, ob ein Browser ein Textfeld automatisch ausgefüllt hat? Besonders bei Benutzernamen- und Passwortfeldern, die beim Laden der Seite automatisch ausgefüllt werden.

Meine erste Frage ist, wann dies in der Seitenladesequenz auftritt. Ist es vor oder nach document.ready?

Zweitens, wie kann ich mithilfe der Logik herausfinden, ob dies geschehen ist? Es ist nicht so, dass ich das verhindern möchte, sondern mich einfach in das Ereignis einhängen. Am liebsten so etwas:

if (autoFilled == true) {

} else {

}

Wenn möglich, würde ich gerne eine jsfiddle sehen, die Ihre Antwort zeigt.

Mögliche Duplikate

DOM-Ereignis zum automatischen Ausfüllen des Browserkennworts?

Vom Browser automatisch ausgefüllte und durch Javascript ausgelöste Ereignisse

- Beide Fragen erklären nicht wirklich, welche Ereignisse ausgelöst werden, sondern überprüfen das Textfeld ständig (nicht gut für die Leistung!).

Nicht definiert
quelle
1
Die Überprüfung dauert einige Mikrosekunden, während das Intervall die Überprüfung etwa alle 100 Millisekunden auslösen würde. Wie wird sich das überhaupt auf die Leistung auswirken? Wenn es ein Ereignis gegeben hätte, das vom Browser ausgelöst wurde, hätten sie es sicher verwendet.
Esailija
Ich verstehe, was Sie meinen, aber es hängt vom ersten Teil meiner Frage ab, ob JavaScript überhaupt weiß, dass gerade eine Änderung stattgefunden hat (z. B. vor document.ready)
Undefined
1
Die beste Lösung für Chrome / WebKit ist die Verwendung des DOM-Selektors: document.querySelectorAll ('input: -webkit-autofill'); nach einer kurzen Verzögerung setTimeout (... Code hier ... 250);
ChrisN
Grundsätzlich möchte ich Benutzer automatisch anmelden, wenn es automatisch ausgefüllt ist, verrückt ärgerlich, sich wieder anzumelden, wenn es sich automatisch abmeldet.
Muhammad Umer
@ChrisN Dein Kommentar hat mir tatsächlich eine (einfache) Lösung gebracht. Ich sehe es jedoch nicht als Antwort! Poste es als eins und pinge mich an, damit ich es dankend verbessern kann.
Ethan Kaminski

Antworten:

123

Das Problem ist, dass das automatische Ausfüllen von verschiedenen Browsern unterschiedlich behandelt wird. Einige senden das Änderungsereignis aus, andere nicht. Es ist daher fast unmöglich, sich an ein Ereignis zu binden, das ausgelöst wird, wenn der Browser ein Eingabefeld automatisch vervollständigt.

  • Ereignisauslöser für verschiedene Browser ändern:

    • Für Felder für Benutzername / Passwort:

      1. Firefox 4, IE 7 und IE 8 lösen das Änderungsereignis nicht aus.
      2. Safari 5 und Chrome 9 lösen das Änderungsereignis aus.
    • Für andere Formularfelder:

      1. IE 7 und IE 8 lösen das Änderungsereignis nicht aus.
      2. Firefox 4 löst das Änderungsänderungsereignis aus, wenn Benutzer einen Wert aus einer Liste von Vorschlägen und einer Registerkarte außerhalb des Felds auswählen.
      3. Chrome 9 löst das Änderungsereignis nicht aus.
      4. Safari 5 löst das Änderungsereignis aus.

Am besten deaktivieren Sie entweder die automatische Vervollständigung für ein Formular mit autocomplete="off" in Ihrem Formular verwendet wird, oder fragen in regelmäßigen Abständen ab, ob es ausgefüllt ist.

Bei Ihrer Frage, ob es auf oder vor dem Dokument ausgefüllt ist, variiert es bereits wieder von Browser zu Browser und sogar von Version zu Version. Für Benutzername / Passwort-Felder wird nur ausgefüllt, wenn Sie ein Benutzername-Passwortfeld auswählen. Insgesamt hätten Sie also einen sehr unordentlichen Code, wenn Sie versuchen, an ein Ereignis anzuhängen.

Sie können dies HIER gut lesen

afrin216
quelle
26
Bitte beachten Sie, dass es einen Unterschied zwischen Autocomplete und Autofill gibt. OP bezieht sich speziell auf Browser, die beim Laden der Seite gespeicherte Anmeldedaten eingeben.
Robbert
2
Ein gewöhnlicher Hack ist ein Mauszentrum auf einem wichtigen Teil der Seite. Das Ereignis wird ausgelöst, wenn der Benutzer mit der Maus auf die Schaltfläche oder eine andere Person drückt.
Bryce
1
@Bryce Persönlich würde ich mit einem "Unschärfe" -Ereignis gehen, da das automatische Ausfüllen etwas ist, das passiert, nachdem Sie den Eingabebereich betreten haben. Natürlich ist es nicht ideal, aber als Fallback für die oben aufgeführten Browser kann es sehr hilfreich sein
JakeJ
Vergiss das inputEreignis nicht. Das ist es, was Chrome bei der automatischen Vervollständigung auslöst (und wahrscheinlich auch beim automatischen Ausfüllen, wenn Chrome das hat; ich schalte dieses Zeug immer aus).
TJ Crowder
Sehen Sie sich meine einzeilige Antwort an, wenn Sie nur wissen möchten, ob der Wert im Textfeld von Google Chrome Autocomplete ausgefüllt wurde.
ThdK
70

Lösung für WebKit-Browser

Aus den MDN-Dokumenten für die : -webkit-autofill CSS -Pseudoklasse :

Die CSS-Pseudoklasse: -webkit-autofill stimmt überein, wenn der Wert eines Elements vom Browser automatisch ausgefüllt wird

Wir können eine CSS-Regel für den ungültigen Übergang für das gewünschte <input>Element definieren, sobald es :-webkit-autofillbearbeitet wurde. JS kann sich dann an die anschließenanimationstart Ereignis anschließen.

Dank an das Klarna UI- Team. Sehen Sie ihre schöne Implementierung hier:

Lev Kazakov
quelle
1
Dies ist bei weitem die beste Lösung! Ein großes Lob an Lev hier dafür. Vielen Dank, dass Sie die Lösung von Klarna UI geteilt haben. Bis ich diese gefunden habe, hat nichts anderes für mich funktioniert. Lebensretter!
Braden Rockwell Napier
1
Neben den CSS-Regeln werden auch die Keyframes hier github.com/klarna/ui/blob/v4.10.0/Field/styles.scss#L181-L189 benötigt
user1069816
Das hat bei mir einwandfrei funktioniert! Muss ein wenig damit herumspielen, um den genauen Ansatz herauszufinden. Vielen Dank, dass Sie Klarna Team
Pritesh
18

Dies funktioniert für mich in den neuesten Versionen von Firefox, Chrome und Edge:

$('#email').on('blur input', function() {
    ....
});
James
quelle
6
'input'! Dies war die einfachste Lösung für mich, aber ich habe nur auf Autocomplete getestet, nicht auf Autofill.
GreenRaccoon23
Unschärfe funktioniert nicht für mich mit einigen Auto-Complete-Add-Ons
Pathfinder
Die Eingabe wird bei jedem Tastendruck ausgelöst. Wenn Sie einen Serveraufruf ausführen, wird dieser möglicherweise zu oft ausgelöst.
RiZKiT
Tolle Lösung! Diese Ereigniskombination löst das Problem mit dem Ausfüllen durch den Benutzer und dem automatischen Ausfüllen durch den Browser.
Petr Hladík
17

Für Google Chrome Autocomplete hat dies bei mir funktioniert:

if ($("#textbox").is(":-webkit-autofill")) 
{    
    // the value in the input field of the form was filled in with google chrome autocomplete
}
ThdK
quelle
Es hat auch bei mir funktioniert. Ich habe Hunderte von Lösungen ausprobiert und niemand hat funktioniert. Vielen Dank, rette meinen Tag und habe immer nach einer Lösung gesucht.
Perozzo
4
Dieser Ansatz führt zu einem Fehler: "Syntaxfehler, nicht erkannter Ausdruck: nicht unterstütztes Pseudo: -webkit-autofill" in anderen Browsern (ich habe es mit Firefox versucht)
anvita surapaneni
1
Wenn nicht mehr so ​​gut wie ab 2020 mit Chrom gearbeitet wird, wird auch ein nicht erkannter Fehlerausdruck ausgegeben: nicht unterstütztes Pseudo: -webkit-autofill
Leo
15

Nur für den Fall, dass jemand nach einer Lösung sucht (so wie ich es heute war), um eine Änderung beim automatischen Ausfüllen des Browsers zu hören, ist hier eine benutzerdefinierte Abfragemethode, die ich erstellt habe, um den Vorgang beim Hinzufügen eines Änderungslisteners zu einer Eingabe zu vereinfachen:

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

Sie können es so nennen:

$("#myInput").allchange(function () {
    alert("change!");
});
LcSalazar
quelle
1
Aus irgendeinem Grund funktioniert dieser Code bei der Seitenumleitung nicht (wenn ich mich von der Anwendung abmelde und zur Anmeldeseite umgeleitet werde, auf der das automatische Ausfüllen erfolgt). Obwohl es bei der Seitenaktualisierung funktioniert.
VishwaKumar
1
das sieht aus wie der mobile Batterieentleerer: /
Stefan Fisk
@StefanFisk - Nicht wirklich. Ein einfacher, sich wiederholender Timer, der auf der JS-Ebene einer Browserseite eingestellt ist, reicht nicht aus, um sich auf Ihren Akku auszuwirken, da auf den meisten Webseiten so viel los ist. Sie glauben wirklich, dass google.com keine wiederkehrenden Timer einstellt? Was für ein Energieverwaltungsfehler wäre es, wenn ich einfach mit JS eine Webseite programmieren könnte, die den Akku eines Benutzers
entlädt
15

Ich habe viel über dieses Problem gelesen und wollte eine sehr schnelle Problemumgehung bereitstellen, die mir geholfen hat.

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

wo inputBackgroundNormalStatefür meine Vorlage ist 'rgb (255, 255, 255)'.

Wenn Browser die automatische Vervollständigung anwenden, deuten sie im Grunde genommen darauf hin, dass die Eingabe automatisch ausgefüllt wird, indem eine andere (störende) gelbe Farbe auf die Eingabe angewendet wird.

Bearbeiten: Dies funktioniert für jeden Browser

DrNio
quelle
Tolles Denken!
Moto
7

Leider ist die einzige zuverlässige Möglichkeit, diesen Cross-Browser zu überprüfen, das Abfragen der Eingabe. Um es ansprechbar zu machen, hören Sie sich auch Ereignisse an. Chrome hat damit begonnen, automatische Füllwerte vor Javascript zu verbergen, das einen Hack benötigt.

  • Umfrage jede halbe bis dritte Sekunde (muss in den meisten Fällen nicht sofort erfolgen)
  • Lösen Sie das Änderungsereignis mit JQuery aus und führen Sie dann Ihre Logik in einer Funktion aus, die das Änderungsereignis abhört.
  • Fügen Sie einen Fix für die versteckten Werte für das automatische Ausfüllen von Chrome-Kennwörtern hinzu.

    $(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);
    });
Eimer
quelle
6

Es gibt eine neue Polyfill-Komponente, um dieses Problem auf Github zu beheben. Schauen Sie sich das AutoFill-Event an . Sie müssen es nur installieren und voilà, das automatische Ausfüllen funktioniert wie erwartet.

bower install autofill-event
David
quelle
Dies funktionierte hervorragend mit jQuery Custom Forms. Ich habe es gerade abgelegt und meine benutzerdefinierten Auswahllisten haben mit dem automatischen Ausfüllen hervorragend funktioniert.
Chris Bloom
6

Meine Lösung:

Hören Sie sich changeEreignisse wie gewohnt an und gehen Sie beim Laden des DOM-Inhalts folgendermaßen vor:

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

Dadurch werden die Änderungsereignisse für alle Felder ausgelöst, die nicht leer sind, bevor der Benutzer die Möglichkeit hatte, sie zu bearbeiten.

Camilo Martin
quelle
Perfekt. Die erste Lösung, die ich bei der Arbeit mit Chrome gefunden habe!
Rid Iculous
3
Es ist wirklich @RidIculous, wie einfach einige Lösungen sein können.
Camilo Martin
3
Aber elem.val () gibt eine leere Zeichenfolge für automatisch ausgefüllte Passwortfelder in Chrome zurück :(
Hemant_Negi
@Hemant_Negi Versendet Chrome das Änderungsereignis nicht trotzdem? Korrigiere mich, wenn ich falsch liege. Ich benutze LastPass und bin zu faul, um es zu deaktivieren, um zu sehen, ob es auch ohne funktioniert.
Camilo Martin
1
Ja, Chrome-Versandänderungsereignis, aber wenn ich versuche, den Wert abzurufen, wird er leer zurückgegeben.
Hemant_Negi
4

Ich hatte auch das gleiche Problem, bei dem das Etikett das automatische Ausfüllen nicht erkannte und die Animation zum Verschieben des Etiketts beim Füllen von Text überlappte und diese Lösung für mich funktionierte.

input:-webkit-autofill ~ label {
    top:-20px;
} 
st0495
quelle
Das ist hilfreich.
Rustyshackleford
Genau das, was ich brauchte :)
Dabrule
4

Ich suchte nach einer ähnlichen Sache. Nur Chrome ... In meinem Fall musste der Wrapper div wissen, ob das Eingabefeld automatisch ausgefüllt wurde. Ich könnte ihm also zusätzliches CSS geben, genau wie Chrome es im Eingabefeld tut, wenn es automatisch ausgefüllt wird. Bei Betrachtung aller obigen Antworten war meine kombinierte Lösung die folgende:

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

Das HTML, damit dies funktioniert, wäre

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

Ich weiß, dass dies ein alter Thread ist, aber ich kann mir vorstellen, dass viele hier kommen, um eine Lösung dafür zu finden.

Zu diesem Zweck können Sie überprüfen, ob die Eingabe (n) Werte hat:

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

Ich benutze dies selbst, um beim Laden nach Werten in meinem Anmeldeformular zu suchen, um die Schaltfläche "Senden" zu aktivieren. Der Code wurde für jQuery erstellt, kann jedoch bei Bedarf leicht geändert werden.

S.Lund
quelle
1
Dieser Code funktioniert gut für mich, wenn Sie die dritte Zeile auf($("#inputID:-webkit-autofill").val().length > 0) {
Hector
3

Dies ist eine Lösung für Browser mit Webkit-Rendering-Engine . Wenn das Formular automatisch ausgefüllt wird, erhalten die Eingaben die Pseudoklasse: -webkit-autofill- ( Eingabe: -webkit-autofill {...}). Dies ist also die Kennung, die Sie über JavaScript überprüfen müssen.

Lösung mit einem Testformular:

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

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

});

Problem beim Laden der Seite ist das Abrufen des Kennwortwerts, sogar der Länge. Dies liegt an der Sicherheit des Browsers. Auch das Timeout , weil der Browser das Formular nach einer bestimmten Zeitfolge ausfüllt.

Dieser Code fügt den gefüllten Eingaben die Klasse auto_filled hinzu . Ich habe auch versucht, den Kennwortwert oder die Länge des Eingabetyps zu überprüfen, aber es hat funktioniert, kurz nachdem ein Ereignis auf der Seite aufgetreten ist. Also habe ich versucht, ein Ereignis auszulösen, aber ohne Erfolg. Im Moment ist dies meine Lösung. Genießen!

Adam Šipický
quelle
Dies ist die aktuelle Antwort.
Ben Racicot
Ich habe diese Lösung ausprobiert und sehr gut für mich gearbeitet. Vielen Dank.
Marcus Crisostomo
2

Ich habe die perfekte Lösung für diese Frage. Probieren Sie dieses Code-Snippet aus.
Demo ist da

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

In Chrome können Sie Felder zum automatischen Ausfüllen erkennen, indem Sie eine spezielle CSS-Regel für automatisch ausgefüllte Elemente festlegen und dann mit Javascript prüfen, ob auf das Element diese Regel angewendet wurde.

Beispiel:

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

Hier ist die CSS-Lösung des Klarna UI-Teams. Sehen Sie ihre nette Implementierung hier Ressource

Funktioniert gut für mich.

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

Ich habe diese Lösung für das gleiche Problem verwendet.

HTML-Code sollte sich folgendermaßen ändern:

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

und jQuery-Code sollte sein in document.ready:

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

Ich habe das Unschärfeereignis für den Benutzernamen verwendet, um zu überprüfen, ob das pwd-Feld automatisch ausgefüllt wurde.

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

Dies funktioniert für IE und sollte für alle anderen Browser funktionieren (ich habe nur IE überprüft)

Bridget Arrington
quelle
@ChrisN Ich habe meine Lösung mit IE getestet. Browser behandeln die Javascsript-Ereignisse unterschiedlich. Meine Lösung ist einfach und leicht zu lesen und für einen der schwierigeren Browser zu programmieren.
Bridget Arrington
1
Am Ende habe ich die gleiche Lösung: blurEreignis. Ich wende die gleiche Funktion für das changeund blurEreignis an und es hat großartig funktioniert. Eine einfache Lösung ohne zusätzliche Bibliotheken.
Paulo Check
0

Ich hatte das gleiche Problem und habe diese Lösung geschrieben.

Beim Laden der Seite wird jedes Eingabefeld abgefragt (ich habe 10 Sekunden eingestellt, aber Sie können diesen Wert einstellen).
Nach 10 Sekunden wird die Abfrage für jedes Eingabefeld beendet und nur für die fokussierte Eingabe (falls vorhanden). Es stoppt, wenn Sie die Eingabe verwischen, und startet erneut, wenn Sie eine fokussieren.

Auf diese Weise fragen Sie nur bei wirklichem Bedarf und nur bei einer gültigen Eingabe ab.

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

Es funktioniert nicht ganz gut, wenn Sie mehrere Werte automatisch einfügen, aber es könnte optimiert werden, um nach jeder Eingabe im aktuellen Formular zu suchen.

Etwas wie:

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

Wenn Sie nur erkennen möchten, ob die automatische Füllung verwendet wurde oder nicht, anstatt genau zu erkennen, wann und zu welchem ​​Feld die automatische Füllung verwendet wurde, können Sie einfach ein verstecktes Element hinzufügen, das automatisch ausgefüllt wird, und dann prüfen, ob dies der Fall ist enthält einen beliebigen Wert. Ich verstehe, dass dies möglicherweise nicht das ist, woran viele Menschen interessiert sind. Stellen Sie das Eingabefeld mit einem negativen tabIndex und mit absoluten Koordinaten weit außerhalb des Bildschirms ein. Es ist wichtig, dass die Eingabe Teil derselben Form ist wie der Rest der Eingabe. Sie müssen einen Namen verwenden, der durch automatisches Ausfüllen erfasst wird (z. B. "zweiter Name").

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

Hängen Sie diese Eingabe an das Formular an und überprüfen Sie den Wert beim Senden des Formulars.

bornSwift
quelle
0

Das tut es eine Lösung dafür zu geben, die nicht auf Abfragen beruht (zumindest für Chrome). Es ist fast genauso hackisch, aber ich denke, es ist geringfügig besser als globale Umfragen.

Stellen Sie sich das folgende Szenario vor:

  1. Der Benutzer beginnt, Feld1 auszufüllen

  2. Der Benutzer wählt einen Vorschlag zur automatischen Vervollständigung aus, der die Felder 2 und 3 automatisch ausfüllt

Lösung: Registrieren Sie eine Unschärfe für alle Felder, die über das folgende jQuery-Snippet $ (': - webkit-autofill') prüft, ob automatisch ausgefüllte Felder vorhanden sind.

Dies wird nicht sofort geschehen, da es verzögert wird, bis der Benutzer Feld1 verwischt, aber es ist nicht auf globale Abfragen angewiesen, daher ist IMO eine bessere Lösung.

Da das Drücken der Eingabetaste ein Formular senden kann, benötigen Sie möglicherweise auch einen entsprechenden Handler für den Tastendruck.

Alternativ können Sie die globale Abfrage verwenden, um $ (': - webkit-autofill') zu überprüfen.

Dan D.
quelle
0

Aus meiner persönlichen Erfahrung funktioniert der folgende Code gut mit Firefox IE und Safari, funktioniert aber nicht sehr gut bei der Auswahl der automatischen Vervollständigung in Chrome.

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

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

Der folgende Code funktioniert besser, da er jedes Mal ausgelöst wird, wenn der Benutzer auf das Eingabefeld klickt. Von dort aus können Sie überprüfen, ob das Eingabefeld leer ist oder nicht.

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

Ich habe es auf Chrom geschafft mit:

    setTimeout(
       function(){
          $("#input_password").focus();
          $("#input_username").focus();
          console.log($("#input_username").val());
          console.log($("#input_password").val());
       }
    ,500);
Antoine O.
quelle
Nicht sicher, wann genau das automatische Ausfüllen von Chrome ausgeführt wird, aber in $ ('Eingabe, Auswahl'). On ('focusin', function (evt) {...}); Ich erhalte bereits automatisch ausgefüllte Werte für alle Felder.
Mirek vor
Neue Version vielleicht?
Antoine O vor
0

Meine Lösung ist:

    $.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
quelle
Eine Erklärung für Ihre Lösung würde helfen
Tonne
Ich dachte es wäre offensichtlich. Grundsätzlich besteht die Idee darin, den Wert des Eingabefelds einige Male zu überprüfen. In der aktuellen Implementierung ist es 10 Mal mit 100 ms Verzögerung. Wenn also während eines zweiten Browsers 10 * 1000 = 1 Sek. Den Wert für das automatische Ausfüllen ausfüllt, wird der an das automatische Ausfüllen übergebene Rückruf aufgerufen. Im aktuellen Beispiel wird nur eine Klasse hinzugefügt. Wenn Sie weitere Fragen haben, zögern Sie bitte nicht und fragen Sie einfach :).
Romick
0

Nach Recherchen besteht das Problem darin, dass Webkit-Browser bei der automatischen Vervollständigung kein Änderungsereignis auslösen. Meine Lösung bestand darin, die vom Webkit hinzugefügte AutoFill-Klasse abzurufen und das Änderungsereignis selbst auszulösen.

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

Hier ist ein Link zum Thema Chrom. https://bugs.chromium.org/p/chromium/issues/detail?id=636425

Cvetan Himchev
quelle
0

Um zum Beispiel E-Mails zu erkennen, habe ich "on change" versucht und ein Mutationsbeobachter hat nicht funktioniert. setInterval funktioniert gut mit der automatischen Füllung von LinkedIn (es wird nicht mein gesamter Code angezeigt, aber Sie haben die Idee), und es funktioniert gut mit dem Backend, wenn Sie hier zusätzliche Bedingungen hinzufügen, um die AJAX zu verlangsamen. Und wenn sich im Formularfeld nichts ändert, z. B. wenn sie nicht zum Bearbeiten ihrer E-Mail eingeben, verhindert lastEmail sinnlose AJAX-Pings.

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

Es fiel mir schwer, das automatische Ausfüllen in Firefox zu erkennen. Dies ist die einzige Lösung, die für mich funktioniert hat:

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

  }); 

Für Chrome verwende ich: if ($(this).css('animation-name') == 'onAutoFillStart')

Für Firefox: if ($(this).val() != '')

Serj
quelle
-2

versuchen Sie es in CSS

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

Schwarzkopf
quelle