如何判断浏览器是否已自动填充文本框?特别是用户名和密码框,自动填充页面加载。

我的第一个问题是,这在页面加载序列中什么时候发生?是在document.ready之前还是之后?

其次,我如何使用逻辑来找出是否发生了这种情况?这不是我想阻止这种情况发生,只是挂钩到事件。最好是这样的:

if (autoFilled == true) {

} else {

}

如果可能的话,我很想看到一个jsfiddle显示你的答案。

可能重复

DOM事件浏览器密码自动填充?

浏览器自动填充和Javascript触发事件

这两个问题都没有真正解释什么事件被触发,它们只是不断地重新检查文本框(对性能不好!)


当前回答

我花了几个小时解决的问题,检测自动填充输入在第一页加载(没有任何用户采取行动),并发现理想的解决方案,工作在Chrome, Opera,边缘和FF太!!

在Chrome, Opera,边缘问题解决得相当EZ

通过搜索带有伪类输入的元素:-webkit-autofill并执行所需的操作(在我的例子中,我更改输入包装器类以使用浮动标签模式更改标签位置)。

问题出在Firefox上

因为FF没有这样的伪类或类似的类(正如许多人建议的“:-moz-autofill”),可以通过简单地搜索DOM来查看。你也找不到输入的黄色背景。唯一的原因是浏览器通过改变过滤器属性添加了这个黄色:

输入:-moz-autofill,输入:-moz-autofill-preview{过滤器:灰度(21%)亮度(88%)对比度(161%)反转(10%)黑褐色(40%)饱和(206%);}

所以在Firefox的情况下,你必须首先搜索所有的输入,并得到它的计算风格,然后比较这个过滤器风格硬编码在浏览器设置。我真的不知道为什么他们不用简单的背景色,而是用那个奇怪的滤镜!?他们让生活更艰难了;)

下面是我的代码在我的网站(https://my.oodo.pl/en/modules/register/login.php):)上工作时的魅力

<script type="text/javascript">
/* 
 * this is my main function
 */
var checkAutoFill = function(){
    /*first we detect if we have FF or other browsers*/
    var isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
    if (!isFirefox) {
        $('input:-webkit-autofill').each(function(){
        /*here i have code that adds "focused" class to my input wrapper and changes 
        info instatus div. U can do what u want*/
        $(this).closest('.field-wrapper').addClass('focused');
        document.getElementById("status").innerHTML = "Your browser autofilled form";
        });
    }
    if (isFirefox) {
        $('input').each(function(){
        var bckgrnd = window.getComputedStyle(document.getElementById(this.id), null).getPropertyValue("background-image");
        if (bckgrnd === 'linear-gradient(rgba(255, 249, 145, 0.5), rgba(255, 249, 145, 0.5))') {
        /*if our input has that filter property customized by browserr with yellow background i do as above (change input wrapper class and change status info. U can add your code here)*/
        $(this).closest('.field-wrapper').addClass('focused');
        document.getElementById("status").innerHTML = "Your Browser autofilled form";
        }
        })
    }
}
/*im runing that function at load time and two times more at 0.5s and 1s delay because not all browsers apply that style imediately (Opera does after ~300ms and so Edge, Chrome is fastest and do it at first function run)*/
checkAutoFill();
setTimeout(function(){ 
checkAutoFill();
}, 500);
setTimeout(function(){ 
checkAutoFill();
}, 1000);
})
</script>

我手动编辑了上面的代码,把一些对你不重要的垃圾扔出去。如果它不为你工作,比粘贴到你的IDE和双重检查语法;)当然,添加一些调试警报或控制台日志并进行自定义。

其他回答

我为angularjs找到了一个有效的解决方案。

诀窍是在以下情况下禁用输入字段的required属性 该指令检测字段是由浏览器通过自动填充填充的。

由于不再需要输入字段,登录提交按钮将被启用。

这即使用户没有点击进入窗口的主体(见Chrome自动填充/自动完成无值密码)。

指令:

angular.module('formtools').directive('autofill', [
        '$interval', function ($interval)
        {
            return {
                scope: false,
                require: 'autofill',
                controller: function AutoFillController(){
                    this.applied = false;
                },
                controllerAs: 'autoFill',
                link: function (scope, elem, attrs, autofill)
                {
                    var refresh = $interval(function() {
                        // attention: this needs jquery, jqlite from angular doesn't provide this method
                        if(elem.is(':-webkit-autofill'))
                        {
                            autofill.applied = true;
                            $interval.cancel(refresh);
                        }
                    }, 100, 100);
                }
            }
        }]);

HTML:

<form name="loginform">

  <input 
     type="text" 
     name="username" 
     autofill 
     ng-required="!autoFill.applied">
  
  <input 
     type="password" 
     name="password" 
     autofill 
     ng-required="!autoFill.applied">
     
  <button ng-disabled="loginform.$invalid">Login</button>   
</form>

如果有人正在寻找一个解决方案(就像我今天一样),来监听浏览器的自动填充更改,这里有一个我已经构建的自定义jquery方法,只是为了简化向输入添加更改侦听器的过程:

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

你可以这样调用它:

$("#myInput").allchange(function () {
    alert("change!");
});

我用这个方法来解决同样的问题。

HTML代码应该改为这样:

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

jQuery代码应该在document.ready中:

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

经过研究发现,webkit浏览器在自动完成时不会触发更改事件。我的解决方案是自己获取webkit添加的自动填充类并触发更改事件。

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

这里是一个链接的问题在铬。https://bugs.chromium.org/p/chromium/issues/detail?id=636425

我读了很多关于这个问题的文章,想提供一个非常快速的解决方法来帮助我。

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

我的模板的inputBackgroundNormalState是'rgb(255,255,255)'。

所以基本上当浏览器应用自动补全时,他们倾向于通过在输入上应用不同的(烦人的)黄色来指示输入是自动填充的。

编辑:这适用于所有浏览器