Détection du remplissage automatique du navigateur

165

Comment savoir si un navigateur a rempli automatiquement une zone de texte? Surtout avec les champs de nom d'utilisateur et de mot de passe qui se remplissent automatiquement autour du chargement de la page.

Ma première question est quand cela se produit-il dans la séquence de chargement de la page? Est-ce avant ou après le document.

Deuxièmement, comment puis-je utiliser la logique pour savoir si cela s'est produit? Ce n'est pas que je veuille empêcher cela de se produire, il suffit de me connecter à l'événement. De préférence quelque chose comme ceci:

if (autoFilled == true) {

} else {

}

Si possible, j'aimerais voir un jsfiddle montrant votre réponse.

Doublons possibles

Événement DOM pour la saisie automatique du mot de passe du navigateur?

Événements déclenchés par le remplissage automatique du navigateur et Javascript

- Ces deux questions n'expliquent pas vraiment quels événements sont déclenchés, elles revérifient continuellement la zone de texte (pas bon pour les performances!).

Indéfini
la source
1
La vérification prend quelques microsecondes alors que l'intervalle déclencherait la vérification toutes les 100 millisecondes environ ... comment cela affectera-t-il les performances? S'il existait un événement déclenché par le navigateur, je suis sûr qu'il l'aurait utilisé.
Esailija le
Je vois ce que vous voulez dire, mais cela dépend de la première partie de ma question de savoir si JavaScript est même conscient qu'un changement vient d'avoir lieu (par exemple avant document.ready)
Undefined
1
LA MEILLEURE solution pour Chrome / WebKit est d'utiliser le sélecteur DOM: document.querySelectorAll ('input: -webkit-autofill'); après un court délai setTimeout (... code ici ... 250);
ChrisN
Fondamentalement, je veux connecter automatiquement l'utilisateur s'il est rempli automatiquement, ce qui est ennuyeux et fou de se reconnecter lorsqu'il se déconnecte automatiquement.
Muhammad Umer
@ChrisN Votre commentaire est ce qui m'a apporté une solution (simple). Mais je ne vois pas cela comme une réponse! Postez-le comme un et envoyez-moi un ping, afin que je puisse voter pour vous en remerciement.
Ethan Kaminski

Réponses:

123

Le problème est que le remplissage automatique est géré différemment par différents navigateurs. Certains envoient l'événement de changement, d'autres non. Il est donc presque impossible de s'accrocher à un événement qui est déclenché lorsque le navigateur remplit automatiquement un champ de saisie.

  • Modifier le déclencheur d'événement pour différents navigateurs:

    • Pour les champs nom d'utilisateur / mot de passe:

      1. Firefox 4, IE 7 et IE 8 ne diffusent pas l'événement de modification.
      2. Safari 5 et Chrome 9 envoient l'événement de modification.
    • Pour les autres champs de formulaire:

      1. IE 7 et IE 8 ne diffusent pas l'événement de modification.
      2. Firefox 4 envoie l'événement de changement de modification lorsque les utilisateurs sélectionnent une valeur dans une liste de suggestions et sortent du champ.
      3. Chrome 9 n'envoie pas l'événement de modification.
      4. Safari 5 envoie l'événement de changement.

Les meilleures options sont de désactiver la saisie semi-automatique pour un formulaire en utilisant autocomplete="off" dans votre formulaire ou d'interroger à intervalles réguliers pour voir s'il est rempli.

Pour votre question de savoir si elle est remplie sur ou avant le document, il varie à nouveau d'un navigateur à l'autre et même d'une version à l'autre. Pour les champs de nom d'utilisateur / mot de passe uniquement lorsque vous sélectionnez un champ de mot de passe de nom d'utilisateur est rempli. Donc, dans l'ensemble, vous auriez un code très compliqué si vous essayez de vous attacher à n'importe quel événement.

Vous pouvez avoir une bonne lecture ICI

afrin216
la source
26
Veuillez noter qu'il existe une différence entre la saisie semi-automatique et la saisie automatique. OP fait spécifiquement référence aux navigateurs remplissant les informations de connexion enregistrées lors du chargement de la page.
Robbert
2
Un hack habituel est un mousenter sur une partie importante de la page. L'événement est déclenché lorsque la souris de l'utilisateur se dirige vers le bouton ou un autre.
Bryce
1
@Bryce Personnellement, j'irais avec un événement «flou» en raison du remplissage automatique étant quelque chose qui se produit après que vous soyez entré dans la zone de saisie. Évidemment, ce n'est pas idéal, mais comme solution de secours pour les navigateurs énumérés ci-dessus, cela peut être très utile
JakeJ
N'oubliez pas l' inputévénement. C'est ce que Chrome déclenche lors de la saisie semi-automatique (et probablement aussi du remplissage automatique, si Chrome a cela; je désactive toujours cette fonctionnalité).
TJ Crowder
Voir ma réponse en une ligne si vous voulez simplement savoir si la valeur dans la zone de texte a été remplie par la saisie semi-automatique de Google Chrome.
ThdK le
72

Solution pour les navigateurs WebKit

À partir de la documentation MDN pour la pseudo-classe CSS : -webkit-autofill :

La pseudo-classe CSS: -webkit-autofill correspond lorsqu'un élément a sa valeur remplie automatiquement par le navigateur

Nous pouvons définir une règle css de transition vide sur l' <input>élément souhaité une fois qu'il est :-webkit-autofillédité. JS pourra alors s'accrocher auanimationstart événement.

Crédits à l' équipe Klarna UI . Voir leur belle mise en œuvre ici:

Lev Kazakov
la source
1
c'est, de loin, la meilleure solution! Félicitations à Lev ici pour cela. Merci d'avoir partagé la solution de Klarna UI ... rien d'autre n'a fonctionné pour moi jusqu'à ce que je trouve cela. Life Saver!
Braden Rockwell Napier
1
En plus des règles CSS, les images clés ici github.com/klarna/ui/blob/v4.10.0/Field/styles.scss#L181-L189 sont également nécessaires
user1069816
Cela a fonctionné parfaitement pour moi! Il faut jouer un peu avec pour comprendre l'approche exacte. Merci l'équipe Klarna
pritesh
18

Cela fonctionne pour moi dans les derniers Firefox, Chrome et Edge:

$('#email').on('blur input', function() {
    ....
});
James
la source
6
'input'! C'était la solution la plus simple pour moi, mais j'ai testé uniquement la saisie semi-automatique, pas la saisie automatique.
GreenRaccoon23
le flou ne fonctionne pas pour moi avec certains modules complémentaires automatiques
pathfinder
L'entrée se déclenchera à chaque pression de touche. Si vous faites un appel au serveur, cela peut se déclencher trop souvent.
RiZKiT
Excellente solution! Cette combinaison d'événements résout le problème de remplissage par utilisateur et de remplissage automatique par navigateur.
Petr Hladík
17

Pour la saisie semi-automatique de Google Chrome, 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
}
ThdK
la source
Cela a fonctionné pour moi aussi. J'ai essayé des centaines de solutions et personne n'a fonctionné. Merci beaucoup, sauve ma journée et toutes les fois où j'ai cherché une solution.
perozzo
4
cette approche trows erreur: "Erreur de syntaxe, expression non reconnue: pseudo non pris en charge: -webkit-autofill" sur d'autres navigateurs (j'ai essayé sur Firefox)
anvita surapaneni
1
Ne fonctionne pas sur Chrome ainsi que sur 2020, génère également une erreur d'expression non reconnue: pseudo non pris en charge: -webkit-autofill
Leo
15

Juste au cas où quelqu'un chercherait une solution (comme je l'étais aujourd'hui), pour écouter un changement de remplissage automatique du navigateur, voici une méthode jquery personnalisée que j'ai créée, juste pour simplifier le processus lors de l'ajout d'un écouteur 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!");
});
LcSalazar
la source
1
Pour une raison quelconque pour moi, ce code ne fonctionne pas sur la redirection de page (lorsque je me déconnecte de l'application et que je suis redirigé vers la page de connexion où le remplissage automatique se produit). Bien que cela fonctionne sur l'actualisation de la page.
VishwaKumar
1
qui ressemble à un draineur de batterie mobile: /
Stefan Fisk
@StefanFisk - Ce n'est pas vraiment le cas. Une simple minuterie répétitive réglée au niveau JS d'une page de navigateur n'est pas suffisante pour avoir un impact sur votre batterie, car il se passe tellement de choses dans la plupart des pages Web ... Vous pensez vraiment que google.com ne définit pas de minuterie récurrente? Quel défaut de gestion de l'alimentation ce serait si je pouvais programmer simplement avec JS une page Web qui draine la batterie d'un utilisateur ...
LcSalazar
15

Je lisais beaucoup sur ce problème 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
  }

inputBackgroundNormalStatepour mon modèle est «rgb (255, 255, 255)».

Donc, fondamentalement, lorsque les navigateurs appliquent la saisie semi-automatique, ils ont tendance à indiquer que l'entrée est remplie automatiquement en appliquant une couleur jaune différente (ennuyeuse) à l'entrée.

Edit: cela fonctionne pour tous les navigateurs

DrNio
la source
Bonne réflexion!
moto
7

Malheureusement, le seul moyen fiable que j'ai trouvé pour vérifier ce navigateur croisé est d'interroger l'entrée. Pour le rendre réactif, écoutez également les événements. Chrome a commencé à masquer les valeurs de remplissage automatique de javascript qui nécessite un piratage.

  • Sondage tous les demi à tiers de seconde (n'a pas besoin d'être instantané dans la plupart des cas)
  • Déclenchez l'événement de modification à l'aide de JQuery, puis effectuez votre logique dans une fonction à l'écoute de l'événement de modification.
  • Ajoutez un correctif pour les valeurs de mot de passe de saisie automatique masquées dans 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);
    });
Seau
la source
6

Il existe un nouveau composant polyfill pour résoudre ce problème sur github. Jetez un œil à autofill-event . Il suffit de l'installer et voilà, le remplissage automatique fonctionne comme prévu.

bower install autofill-event
David
la source
Cela a très bien fonctionné avec les formulaires personnalisés jQuery. Je viens de le déposer et mes listes de sélection personnalisées fonctionnaient très bien avec le remplissage automatique.
Chris Bloom
6

Ma solution:

Écoutez les changeévénements comme vous le feriez normalement, et lors du chargement du contenu DOM, procédez comme suit:

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

Cela déclenchera les événements de modification pour tous les champs qui ne sont pas vides avant que l'utilisateur ait eu la possibilité de les modifier.

Camilo Martin
la source
Parfait. La première solution que j'ai trouvée en travaillant avec Chrome!
Rid Iculous le
3
C'est vraiment @RidIculous à quel point certaines solutions peuvent être simples.
Camilo Martin
3
Mais elem.val () renvoie une chaîne vide pour les champs de mot de passe
remplis
@Hemant_Negi Chrome n'envoie-t-il pas l'événement de modification de toute façon? Corrige moi si je me trompe. J'utilise LastPass et je suis trop paresseux pour le désactiver pour voir s'il fonctionne également sans.
Camilo Martin
1
Oui, événement de changement de distribution de chrome, mais lorsque j'essaie de récupérer la valeur, il renvoie vide.
Hemant_Negi
4

J'ai également rencontré le même problème où l'étiquette ne détectait pas le remplissage automatique et l'animation pour déplacer l'étiquette sur le texte de remplissage se chevauchait et cette solution a fonctionné pour moi.

input:-webkit-autofill ~ label {
    top:-20px;
} 
st0495
la source
Ceci est utile.
rustyshackleford
Exactement ce dont j'avais besoin :)
Dabrule
4

Je cherchais une chose similaire. Chrome uniquement ... Dans mon cas, le div wrapper avait besoin de savoir si le champ de saisie était rempli automatiquement. Je pourrais donc lui donner un css supplémentaire, tout comme Chrome le fait dans le champ de saisie lorsqu'il le remplit automatiquement. En regardant toutes les réponses ci-dessus, ma solution combinée é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>
Julesezaar
la source
3

Je sais que c'est un vieux fil, mais j'imagine que beaucoup viennent pour trouver une solution à cela ici.

Pour ce faire, vous pouvez vérifier si la ou les entrées ont des valeurs avec:

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

Je l'utilise moi-même pour vérifier les valeurs dans mon formulaire de connexion lorsqu'il est chargé pour activer le bouton d'envoi. Le code est fait pour jQuery mais est facile à changer si nécessaire.

S.Lund
la source
1
Ce code fonctionne très bien pour moi si vous mettez à jour la troisième ligne vers($("#inputID:-webkit-autofill").val().length > 0) {
Hector
3

C'est une solution pour les navigateurs avec un moteur de rendu webkit . Lorsque le formulaire est rempli automatiquement, les entrées obtiendront la pseudo classe : -webkit-autofill- (par exemple, entrée: -webkit-autofill {...}). C'est donc l'identifiant que vous devez vérifier via JavaScript.

Solution avec un formulaire de test:

<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 la page se charge est d'obtenir la valeur du mot de passe, même la longueur. C'est parce que la sécurité du navigateur. Aussi le délai d'expiration , c'est parce que le navigateur remplira le formulaire après un certain temps.

Ce code ajoutera la classe auto_filled aux entrées remplies. De plus, j'ai essayé de vérifier la valeur ou la longueur du mot de passe du type d'entrée, mais cela a fonctionné juste après qu'un événement sur la page se soit produit. J'ai donc essayé de déclencher un événement, mais sans succès. Pour l'instant c'est ma solution. Prendre plaisir!

Adam Šipický
la source
Ceci est la réponse à jour.
Ben Racicot
J'ai essayé cette solution et j'ai très bien fonctionné pour moi. Merci beaucoup.
Marcus Crisostomo
2

J'ai une solution parfaite pour cette question, essayez cet extrait de code.
La démo est là

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
la source
2

Sur Chrome, vous pouvez détecter les champs de remplissage automatique en définissant une règle css spéciale pour les éléments remplis automatiquement, puis en vérifiant avec javascript si cette règle est appliquée à l'élément.

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"))
Pietro Coelho
la source
2

Voici la solution CSS tirée de l'équipe de Klarna UI. Voir leur belle implémentation ici ressource

Fonctionne bien pour moi.

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

J'ai utilisé cette solution pour le même problème.

Le code HTML devrait changer comme suit:

<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');
});
a828h
la source
0

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 vérifié IE)

Bridget Arrington
la source
@ChrisN J'ai testé ma solution avec IE, les navigateurs gèrent différemment les événements javascsript. Ma solution est simple et facile à lire et s'adresse à l'un des navigateurs les plus difficiles à coder.
Bridget Arrington
1
Je me retrouve avec la même solution: l' blurévénement. Je demande la même fonction pour le changeet blurévénement et il a très bien fonctionné. Une solution simple sans bibliothèques supplémentaires.
Paulo Check
0

J'ai eu le même problème et j'ai écrit cette solution.

Il commence à interroger chaque champ de saisie lorsque la page se charge (j'ai défini 10 secondes mais vous pouvez régler cette valeur).
Après 10 secondes, il arrête d'interroger sur chaque champ d'entrée et il commence à interroger uniquement sur l'entrée focalisée (le cas échéant). Il s'arrête lorsque vous floutez l'entrée et recommence si vous en faites la mise au point.

De cette façon, vous n'interrogez que lorsque cela est vraiment nécessaire et uniquement 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 lorsque plusieurs valeurs sont insérées automatiquement, mais il pourrait être modifié à la recherche de chaque entrée du formulaire actuel.

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);
});
Fès Vrasta
la source
0

Si vous souhaitez uniquement détecter si le remplissage automatique a été utilisé ou non, plutôt que de détecter exactement quand et dans quel champ le remplissage automatique a été utilisé, vous pouvez simplement ajouter un élément caché qui sera rempli automatiquement, puis vérifier si cela contient n'importe quelle valeur. Je comprends que ce n'est peut-être pas ce qui intéresse beaucoup de gens. Définissez le champ de saisie avec un tabIndex négatif et avec des coordonnées absolues bien en dehors de l'écran. Il est important que l'entrée fasse partie du même formulaire que le reste de l'entrée. Vous devez utiliser un nom qui sera récupéré par Auto-fill (ex. "Secondname").

var autofilldetect = document.createElement('input');
autofilldetect.style.position = 'absolute';
autofilldetect.style.top = '-100em';
autofilldetect.style.left = '-100em';
autofilldetect.type = 'text';
autofilldetect.name = 'secondname';
autofilldetect.tabIndex = '-1';

Ajoutez cette entrée au formulaire et vérifiez sa valeur lors de l'envoi du formulaire.

néSwift
la source
0

Il ne fait semble y avoir une solution à ce qui ne repose pas sur les sondages (au moins pour Chrome). C'est presque aussi hackish, mais je pense que c'est légèrement meilleur qu'un sondage mondial.

Considérez le scénario suivant:

  1. L'utilisateur commence à remplir le champ 1

  2. L'utilisateur sélectionne une suggestion de saisie semi-automatique qui remplit automatiquement le champ2 et le champ3

Solution: enregistrez un onblur sur tous les champs qui vérifie la présence de champs remplis automatiquement via l'extrait de code jQuery $ (': - webkit-autofill')

Ce ne sera pas immédiat car il sera retardé jusqu'à ce que l'utilisateur brouille le champ1 mais il ne repose pas sur un sondage global, donc l'OMI, c'est une meilleure solution.

Cela dit, étant donné que le fait d'appuyer sur la touche Entrée peut soumettre un formulaire, vous pouvez également avoir besoin d'un gestionnaire correspondant pour onkeypress.

Vous pouvez également utiliser le sondage global pour vérifier $ (': - webkit-autofill')

Dan D
la source
0

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 pour choisir la saisie semi-automatique dans Chrome.

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

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

Le code ci-dessous fonctionne mieux, car il se déclenchera à chaque fois que l'utilisateur clique sur le champ de saisie et à partir de là, vous pouvez vérifier que le champ de saisie est vide ou non.

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

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);
Antoine O
la source
Je ne sais pas quand exactement le remplissage automatique de Chrome s'exécute, mais dans $ ('input, select'). On ('focusin', function (evt) {...}); Je reçois déjà des valeurs remplies automatiquement pour tous les champs.
mirek
Nouvelle version peut-être?
Antoine O
0

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');
          }
      );
  });
Romick
la source
Une explication de votre solution aiderait
tonne
Je pensais que c'était évidemment. Donc, fondamentalement, l'idée est de vérifier la valeur du champ d'entrée plusieurs fois. Dans la mise en œuvre actuelle, il est de 10 fois avec un retard de 100 ms. Ainsi, lorsque pendant un second navigateur 10 * 1000 = 1sec remplissez la valeur de saisie automatique, le rappel passé à la saisie automatique sera appelé. Dans l'exemple actuel, il ajoute simplement une classe. Si vous avez d'autres questions, n'hésitez pas et demandez simplement :).
Romick
0

Après recherche, le problème est que les navigateurs Webkit ne déclenchent pas d'événement de modification lors de la saisie semi-automatique. Ma solution consistait à obtenir la classe de remplissage automatique ajoutée par Webkit et à déclencher un événement de modification 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

Cvetan Himchev
la source
0

Pour détecter les e-mails par exemple, j'ai essayé "on change" et un observateur de mutation, ni l'un ni l'autre n'a fonctionné. setInterval fonctionne bien avec le remplissage automatique de LinkedIn (ne révélant pas tout mon code, mais vous avez l'idée) et il joue bien avec le backend si vous ajoutez ici des conditions supplémentaires pour ralentir l'AJAX. Et s'il n'y a pas de changement dans le champ du formulaire, comme s'ils ne tapent pas pour modifier leur e-mail, le dernierEmail empêche les pings AJAX inutiles.

// 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
la source
0

J'ai eu du mal à détecter le remplissage automatique dans Firefox. C'est la seule solution qui a fonctionné pour moi:

Démo

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

  }); 

Pour Chrome, j'utilise: if ($(this).css('animation-name') == 'onAutoFillStart')

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

Serj
la source
-2

essayer en CSS

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

schwarzkopf
la source