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

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

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

if (autoFilled == true) {

} else {

}

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

可能重复

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

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

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


当前回答

我为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>

其他回答

我的解决方案是:

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

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

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

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

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

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

这是一个解决方案的浏览器与webkit渲染引擎。 当表单被自动填充时,输入将获得伪类:-webkit-autofill- (f.e. input:-webkit-autofill{…})。这是你必须通过JavaScript检查的标识符。

带有某种测试形式的解:

<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>

和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);

});

页面加载时的问题是获取密码值,甚至长度。这是因为浏览器的安全性。还有超时,这是因为浏览器会在一段时间序列后填充表单。

这段代码将把类auto_filled添加到填充的输入中。此外,我尝试检查输入类型的密码值或长度,但它只是在页面上发生的一些事件后工作。所以我试图触发一些事件,但没有成功。现在这是我的解。 享受吧!

问题是不同的浏览器处理自动填充的方式不同。有些调度变更事件,有些则不调度。因此,当浏览器自动完成一个输入字段时,几乎不可能钩到一个事件。

更改不同浏览器的事件触发器: 对于用户名/密码字段: Firefox 4、IE 7和IE 8不分派更改事件。 Safari 5和Chrome 9会分派更改事件。 对于其他表单字段: ie7和ie8不分派变更事件。 当用户从建议列表中选择一个值并从字段中选择tab时,Firefox 4会分派change change事件。 Chrome 9不会分派更改事件。 Safari 5确实分派了更改事件。

你最好的选择是在你的表单中使用autocomplete="off"来禁用表单的自动完成功能,或者定期轮询查看它是否已填充。

关于你问的是在文件上还是之前填写的问题。不同浏览器,甚至不同版本都不一样。对于用户名/密码字段,仅当您选择用户名时才填写密码字段。因此,如果你试图附加到任何事件,你会有一个非常混乱的代码。

你可以在这里好好阅读一下

我遇到过同样的问题,我已经写出了这个解。

当页面加载时,它开始对每个输入字段进行轮询(我设置了10秒,但您可以调优这个值)。 10秒后,它将停止对每个输入字段的轮询,只对集中的输入(如果有的话)开始轮询。 当你模糊输入时,它会停止,如果你聚焦一个,它又会开始。

通过这种方式,您只在真正需要时轮询,并且只对有效输入进行轮询。

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

当自动插入多个值时,它的工作效果不太好,但可以对它进行调整,查找当前表单上的每个输入。

喜欢的东西:

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