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!).

119
demandé sur Community 2012-07-29 13:20:06

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:

      1. Firefox 4, IE 7, et IE 8 don't envoyez l'événement de changement.
      2. Safari 5 et Chrome 9 envoient l'événement de changement.
    • pour les autres champs du formulaire:

      1. IE 7 et IE 8 ne pas distribuer l'événement change.
      2. 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.
      3. Chrome 9 n'expédie pas le événement de changement.
      4. 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

102
répondu afrin216 2013-03-01 23:21:42

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:

33
répondu Lev Kazakov 2017-01-08 06:35:59

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!");
});
14
répondu LcSalazar 2014-08-19 21:14:38

cela fonctionne pour moi dans le dernier Firefox, Chrome, et bord:

$('#email').on('blur input', function() {
    ....
});
13
répondu James 2016-06-01 18:36:16

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
}
11
répondu ThdK 2016-05-24 07:36:46

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
6
répondu David 2014-04-27 23:16:46

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);
    });
    
6
répondu Bucket 2014-07-16 15:06:49

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
  }

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

6
répondu DrNio 2018-06-13 12:42:16

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.

4
répondu Camilo Martin 2014-09-13 23:28:41

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>
2
répondu Suresh Pattu 2017-06-26 09:54:55

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"))
2
répondu Pietro Coelho 2017-10-11 19:10:50

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>
2
répondu Julesezaar 2018-06-04 07:54:10

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.

1
répondu S.Lund 2014-04-10 21:15:20

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');
});
1
répondu amir2h 2017-12-28 14:08:34

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;
} 
1
répondu st0495 2018-05-12 15:28:23

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)

0
répondu Bridget Arrington 2014-04-30 13:32:26

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);
});
0
répondu Fez Vrasta 2014-10-24 08:43:27

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.

0
répondu bornSwift 2015-12-02 02:21:06

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:

  1. L'utilisateur commence à remplir la Zone 1

  2. 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')

0
répondu Dan D 2016-04-01 18:19:58

d'essayer CSS

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

0
répondu schwarzkopf 2016-07-10 19:48:10

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();
});
0
répondu MayField 2017-01-25 09:45:46

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);
0
répondu Antoine O 2017-05-10 15:11:35

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');
          }
      );
  });
0
répondu Romick 2017-06-20 11:39:02

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

0
répondu Cvetan Himchev 2017-09-28 13:34:32

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!

0
répondu Adam Šipický 2018-02-12 17:22:56

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;
}
0
répondu zdrsoft 2018-09-05 13:28:16