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

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

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

if (autoFilled == true) {

} else {

}

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

可能重复

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

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

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


当前回答

您可以尝试检测并清除所有自动填充

 var autofillclear = false;
  setInterval(function() {
    if ($("input:-webkit-autofill") && autofillclear == false) {
      $("input:-webkit-autofill").each(function() {
        if ($(this).val() != '') {
          $(this).val('');
          autofillclear = true;
        }
      });
    }
   }, 500);

其他回答

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

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

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

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

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

在Chrome和Edge(2020)中检查:-webkit-autofill会告诉你输入已经填充。但是,在用户以某种方式与页面交互之前,JavaScript无法获得输入中的值。

使用$('x').focus()和$('x').blur()或在代码中触发鼠标事件都没有帮助。

参见https://stackoverflow.com/a/35783761/32429

我在用户名上使用了blur事件来检查pwd字段是否已被自动填充。

 $('#userNameTextBox').blur(function () {
        if ($('#userNameTextBox').val() == "") {
            $('#userNameTextBox').val("User Name");
        }
        if ($('#passwordTextBox').val() != "") {
            $('#passwordTextBoxClear').hide(); // textbox with "Password" text in it
            $('#passwordTextBox').show();
        }
    });

这适用于IE,应该适用于所有其他浏览器(我只检查了IE)

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

好吧,如果我们谈论的是控制输入,这可能是一个可能的解决方案:

    useEffect(() => {
      const inputEl = inputRef.current
      inputEl.addEventListener('focusout', () => props.onChange(inputRef.value))
    }, [])

注意,这可能会导致不必要的渲染。这种解决方案的优点是简单性和所有浏览器的支持。在小型形式中使用这种方法似乎是完全可以接受的。