Detecting Browser Autofill

2018-12-31 13:45发布

How do you tell if a browser has auto filled a text-box? Especially with username & password boxes that autofill around page load.

My first question is when does this occur in the page load sequence? Is it before or after document.ready?

Secondly how can I use logic to find out if this occurred? Its not that i want to stop this from occurring, just hook into the event. Preferably something like this:

if (autoFilled == true) {

} else {

}

If possible I would love to see a jsfiddle showing your answer.

Possible duplicates

DOM event for browser password autofill?

Browser Autofill and Javascript triggered events

--Both these questions don't really explain what events are triggered, they just continuously recheck the text-box (not good for performance!).

26条回答
荒废的爱情
2楼-- · 2018-12-31 13:52

I used this solution for same problem.

HTML code should change to this:

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

and jQuery code should be in document.ready:

$('#txt_password').focus(function(){
    $(this).attr('type','password');
});
查看更多
与君花间醉酒
3楼-- · 2018-12-31 13:54

I was looking for a similar thing. Chrome only... In my case the wrapper div needed to know if the input field was autofilled. So I could give it extra css just like Chrome does on the input field when it autofills it. By looking at all the answers above my combined solution was the following:

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

The html for this to work would be

<div class="input-wrapper">
    <input type="text" name="firstname">
</div>
查看更多
呛了眼睛熬了心
4楼-- · 2018-12-31 13:54

On chrome, you can detect autofill fields by settings a special css rule for autofilled elements, and then checking with javascript if the element has that rule applied.

Example:

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"))
查看更多
孤独寂梦人
5楼-- · 2018-12-31 13:55

I was reading a lot about this issue and wanted to provide a very quick workaround that helped me.

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

where inputBackgroundNormalState for my template is 'rgb(255, 255, 255)'.

So basically when browsers apply autocomplete they tend to indicate that the input is autofilled by applying a different (annoying) yellow color on the input.

Edit : it will work for every browser

查看更多
情到深处是孤独
6楼-- · 2018-12-31 13:55

After research the issue is that webkit browsers does not fire change event on autocomplete. My solution was to get the autofill class that webkit adds and trigger change event by myself.

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

Here is a link for the issue in chromium. https://bugs.chromium.org/p/chromium/issues/detail?id=636425

查看更多
浅入江南
7楼-- · 2018-12-31 13:57

I have perfect solution for this question try this code snippet.
Demo is here

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>

查看更多
登录 后发表回答