La Détection De Navigateur De Remplissage Automatique
Comment savoir si un navigateur a rempli automatiquement une zone de texte? En particulier avec les boîtes de nom d'utilisateur et de mot de passe qui auto-remplir autour du chargement de page.
ma première question Est de savoir quand cela se produit dans la séquence de chargement de la page? Est-ce avant ou après document.est-il prêt?
Deuxièmement, comment puis-je utiliser la logique pour savoir si cela se produisait? Ce n'est pas que je veux empêcher cela de se produire, juste accrochez-vous à l'événement. De préférence quelque chose comme ceci:
if (autoFilled == true) {
} else {
}
si possible, j'aimerais voir un jsfiddle montrer votre réponse.
duplicata possibles
DOM événement pour le navigateur mot de passe remplissage automatique?
événements déclenchés par le navigateur et Javascript
--ces deux questions n'expliquent pas vraiment les événements qui sont déclenchés, ils revérifient continuellement les zone de texte (pas bon pour la performance!).
26 réponses
le problème est autofill est traitée différemment par différents navigateurs. Certains répartissent le changement, d'autres non. Il est donc presque impossible de s'accrocher à un événement qui est déclenché lorsque le navigateur autocomplète un champ d'entrée.
-
déclencheur D'événement de changement pour différents navigateurs:
-
pour les champs Nom d'utilisateur/mot de passe:
- Firefox 4, IE 7, et IE 8 don't envoyez l'événement de changement.
- Safari 5 et Chrome 9 envoient l'événement de changement.
-
pour les autres champs du formulaire:
- IE 7 et IE 8 ne pas distribuer l'événement change.
- Firefox 4 envoie l'événement de changement de changement lorsque les utilisateurs choisissent une valeur à partir d'une liste de suggestions et d'onglet hors du champ.
- Chrome 9 n'expédie pas le événement de changement.
- Safari 5 envoie l'événement de changement.
-
vos meilleures options sont de désactiver autocomplete pour un formulaire en utilisant autocomplete="off"
dans votre formulaire ou un sondage à intervalle régulier pour voir si son rempli.
pour votre question à savoir si elle est remplie sur ou avant le document.prêt encore, il varie d'un navigateur à l'autre et même d'une version à l'autre. Pour champs Nom d'utilisateur/mot de passe seulement lorsque vous sélectionnez un champ Nom d'utilisateur mot de passe est rempli. Donc, dans l'ensemble, vous auriez un code très désordonné si vous essayez d'attacher à n'importe quel événement.
vous pouvez avoir une bonne lecture sur ce ici
Solution pour les navigateurs WebKit
des Docs MDN pour le :- webkit-autofill CSS pseudo-class:
L' :-webkit-remplissage automatique de la CSS pseudo-classe correspond quand un élément a sa valeur remplis automatiquement par le navigateur
nous pouvons définir un vide transition règle css sur l'élément désiré <input>
une fois qu'il est :-webkit-autofill
ed. JS sera alors en mesure de s'accrocher à l'événement animationstart
.
crédits à L'équipe Klarna UI . Voir leur belle mise en œuvre ici:
juste au cas où quelqu'un est à la recherche d'une solution (comme je l'étais aujourd'hui), pour écouter un changement auto-remplir de navigateur, voici une méthode jQuery personnalisé que j'ai construit, juste pour simplifier le processus lors de l'ajout d'un auditeur de changement à une entrée:
$.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);
};
, Vous pouvez l'appeler comme ceci:
$("#myInput").allchange(function () {
alert("change!");
});
cela fonctionne pour moi dans le dernier Firefox, Chrome, et bord:
$('#email').on('blur input', function() {
....
});
pour google chrome autocomplete, cela a fonctionné pour moi:
if ($("#textbox").is(":-webkit-autofill"))
{
// the value in the input field of the form was filled in with google chrome autocomplete
}
il y a un nouveau composant polyfill pour régler ce problème sur github. Jetez un oeil à remplissage automatique-événement . Juste besoin de bower l'installer et voilà, autofill fonctionne comme prévu.
bower install autofill-event
malheureusement le seul moyen fiable que j'ai trouvé pour vérifier ce navigateur croisé est de sonder l'entrée. Pour le rendre réactif aussi écouter les événements. Chrome a commencé à cacher les valeurs de remplissage automatique de javascript qui a besoin d'un piratage.
- Sondage chaque moitié à des tiers de seconde ( N'a pas besoin d'être instantanée dans la plupart des cas )
- déclenchez L'événement de changement en utilisant JQuery puis faites votre logique dans une fonction écoutant l'événement de changement.
-
ajouter une correction pour les valeurs de mots de passe Auto-remplir cachés 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); });
je lisais beaucoup sur cette question et je voulais fournir une solution de contournement très rapide qui m'a aidé.
let style = window.getComputedStyle(document.getElementById('email'))
if (style && style.backgroundColor !== inputBackgroundNormalState) {
this.inputAutofilledByBrowser = true
}
où inputBackgroundNormalState
pour mon modèle est " rgb(255, 255, 255)'.
donc fondamentalement, lorsque les navigateurs appliquent autocomplete ils ont tendance à indiquer que l'entrée est auto-remplie en appliquant une couleur jaune (ennuyeux) différente sur l'entrée.
Edit : il fonctionnera pour chaque navigateur
ma solution:
Écouter change
des événements comme vous le feriez normalement, et sur la cathédrale de chargement de contenu, faire ceci:
setTimeout(function() {
$('input').each(function() {
var elem = $(this);
if (elem.val()) elem.change();
})
}, 250);
cela déclenchera les événements de changement pour tous les champs qui ne sont pas vides avant que l'utilisateur ait eu la chance de les éditer.
j'ai la solution parfaite pour cette question essayez ce code snippet.
la démo est ici
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>
sur chrome, vous pouvez détecter les champs auto-remplir en paramétrant une règle css spéciale pour les éléments auto-remplir, puis en vérifiant avec javascript si l'élément a cette règle appliquée.
exemple:
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"))
je cherchais une chose similaire. Chrome seulement... Dans mon cas, le div wrapper devait savoir si le champ input était rempli automatiquement. Donc je pourrais lui donner des css supplémentaires comme le fait Chrome sur le champ d'entrée quand il le remplit automatiquement. En regardant toutes les réponses au-dessus de ma solution était la suivante:
/*
* 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);
le html pour que cela fonctionne serait
<div class="input-wrapper">
<input type="text" name="firstname">
</div>
je sais que c'est un vieux fil, mais je peux imaginer que beaucoup viennent trouver une solution ici.
Pour ce faire, vous pouvez vérifier si l'entrée(s) valeur(s) avec:
$(function() {
setTimeout(function() {
if ($("#inputID").val().length > 0) {
// YOUR CODE
}
}, 100);
});
j'utilise moi-même pour vérifier les valeurs dans mon formulaire de connexion lorsqu'il est chargé d'activer le bouton "soumettre". Le code est fait pour jQuery mais est facile à changer si nécessaire.
j'ai utilisé cette solution pour le même problème.
le code HTML doit changer pour ceci:
<input type="text" name="username" />
<input type="text" name="password" id="txt_password" />
et le code jQuery doit être dans document.ready
:
$('#txt_password').focus(function(){
$(this).attr('type','password');
});
j'ai également fait face au même problème où label n'a pas détecté autofill et animation pour déplacer label sur le texte de remplissage se chevauchait et cette solution a fonctionné pour moi.
input:-webkit-autofill ~ label {
top:-20px;
}
j'ai utilisé l'événement flou sur le nom d'utilisateur pour vérifier si le champ pwd avait été rempli automatiquement.
$('#userNameTextBox').blur(function () {
if ($('#userNameTextBox').val() == "") {
$('#userNameTextBox').val("User Name");
}
if ($('#passwordTextBox').val() != "") {
$('#passwordTextBoxClear').hide(); // textbox with "Password" text in it
$('#passwordTextBox').show();
}
});
cela fonctionne pour IE, et devrait fonctionner pour tous les autres navigateurs (j'ai seulement coché IE)
j'ai eu le même problème et j'ai écrit cette solution.
il démarre le sondage sur chaque champ d'entrée lors du chargement de la page (j'ai mis 10 secondes mais vous pouvez ajuster cette valeur).
Après 10 secondes, l'arrêt de vote sur chaque champ d'entrée et il commence interrogation uniquement sur la porté d'entrée (si).
Il s'arrête lorsque vous floutez l'entrée et recommence si vous en focalisez une.
de cette façon, vous sondez seulement quand vraiment nécessaire et seulement sur une entrée valide.
// 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);
});
cela ne fonctionne pas très bien quand vous avez plusieurs valeurs insérées automatiquement, mais il pourrait être modifié en recherchant chaque entrée sur le formulaire courant.
quelque chose comme:
// 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);
});
si vous voulez seulement détecter si auto-fill a été utilisé ou non, plutôt que de détecter exactement quand et à quel champ auto-fill a été utilisé, vous pouvez simplement ajouter un élément caché qui sera auto-rempli et ensuite vérifier si cela contient une valeur. Je comprends que ce n'est peut-être pas ce qui intéresse beaucoup de gens. Définissez le champ d'entrée avec un tabIndex négatif et avec des coordonnées absolues bien loin de l'écran. Il est important que l'entrée est partie de la même forme que le reste de l'entrée. Vous devez utiliser un nom qui sera repris par l'Auto-remplissage (ex. "secondname").
var autofilldetect = document.createElement('input');
autofilldetect.style.position = 'absolute';
autofilldetect.style.top = '-100em';
autofilldetect.style.left = '-100em';
autofilldetect.type = 'text';
autofilldetect.name = 'secondname';
autofilldetect.tabIndex = '-1';
ajouter cette entrée au formulaire et vérifier sa valeur sur le formulaire soumettre.
il ne semble être une solution à ce qui ne repose pas sur le sondage (au moins pour le Chrome). C'est presque aussi hackish, mais je pense que c'est légèrement mieux que Global polling.
envisager le scénario suivant:
-
L'utilisateur commence à remplir la Zone 1
-
l'utilisateur sélectionne une suggestion autocomplète qu'autofills field2 et field3
Solution: enregistrer un onblur sur tous les champs qui vérifie la présence de champs auto-remplis via l'extrait de jQuery suivant $(':- webkit-autofill')
ce ne sera pas immédiat car il sera retardé jusqu'à ce que l'utilisateur floue field1, mais il ne s'appuie pas sur Global polling donc IMO, c'est une meilleure solution.
cela dit, Puisque frapper la touche enter peut soumettre un formulaire, vous pouvez également avoir besoin d'un correspondant gestionnaire pour onkeypress.
alternativement, vous pouvez utiliser Global polling pour vérifier $(':- webkit-autofill')
d'essayer CSS
input:-webkit-autofill {
border-color: #9B9FC4 !important;
}
D'après mon expérience personnelle, le code ci-dessous fonctionne bien avec firefox IE et safari, mais ne fonctionne pas très bien à la cueillette autocomplete dans chrome.
function check(){
clearTimeout(timeObj);
timeObj = setTimeout(function(){
if($('#email').val()){
//do something
}
},1500);
}
$('#email').bind('focus change blur',function(){
check();
});
ci-dessous le code fonctionne mieux, parce qu'il se déclenche chaque fois que l'utilisateur clique sur le champ d'entrée et de là, vous pouvez vérifier soit le champ d'entrée est vide ou non.
$('#email').bind('click', function(){
check();
});
j'ai réussi sur chrome avec:
setTimeout(
function(){
$("#input_password").focus();
$("#input_username").focus();
console.log($("#input_username").val());
console.log($("#input_password").val());
}
,500);
ma solution est:
$.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');
}
);
});
après la recherche, le problème est que les navigateurs webkit ne démarre pas l'événement de changement sur autocomplete. Ma solution a été d'obtenir la classe autofill que webkit ajoute et de déclencher l'événement de changement par moi-même.
setTimeout(function() {
if($('input:-webkit-autofill').length > 0) {
//do some stuff
}
},300)
voici un lien pour le problème du chrome. https://bugs.chromium.org/p/chromium/issues/detail?id=636425
C'est la solution pour les navigateurs avec WebKit moteur de rendu . Lorsque le formulaire est rempli automatiquement, les entrées reçoivent la pseudo classe :-webkit-autofill- (F. E. input: - webkit-autofill {...}). Voici donc l'identificateur que vous devez vérifier au moyen de JavaScript.
Solution avec une forme d'épreuve quelconque:
<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>
et 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);
});
problème lorsque le chargement de la page est get valeur du mot de passe, même longueur. C'est parce que la sécurité du navigateur. Aussi le timeout , c'est parce que le navigateur remplira le formulaire après une certaine séquence de temps.
ce code ajoutera la classe rempli automatiquement aux entrées remplies. Aussi, j'ai essayé de vérifier la valeur de mot de passe de type d'entrée, ou la longueur, mais cela a fonctionné juste après qu'un événement sur la page est arrivé. J'ai essayé de déclencher un évènement, mais sans succès. Pour l'instant c'est ma solution. Profitez-en!
Voici la solution CSS de L'équipe de Klarna UI. Voir leur mise en œuvre ici ressource
me va très bien.
input:-webkit-autofill {
animation-name: onAutoFillStart;
transition: background-color 50000s ease-in-out 0s;
}
input:not(:-webkit-autofill) {
animation-name: onAutoFillCancel;
}