检测浏览器自动填充

Und*_*ned 147 javascript jquery events autofill event-handling

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

我的第一个问题是在页面加载序列中何时发生这种情况?是在document.ready之前还是之后?

其次,我如何使用逻辑来确定是否发生这种情况?它不是我想阻止这种情况发生,只是挂钩事件.最好是这样的:

if (autoFilled == true) {

} else {

}
Run Code Online (Sandbox Code Playgroud)

如果可能的话,我很乐意看到一个jsfiddle显示你的答案.

可能重复

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

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

- 这些问题并没有真正解释触发了什么事件,他们只是不断重新检查文本框(不利于性能!).

afr*_*216 117

问题是自动填充由不同的浏览器以不同的方式处理.有些人发送变更事件,有些则没有.因此,几乎不可能挂钩浏览器自动填充输入字段时触发的事件.

  • 更改不同浏览器的事件触发器:

    • 对于用户名/密码字段:

      1. Firefox 4,IE 7和IE 8不会发送更改事件.
      2. Safari 5和Chrome 9会发送更改事件.
    • 对于其他表单字段:

      1. IE 7和IE 8不会发送更改事件.
      2. 当用户从字段中的建议列表和选项卡中选择一个值时,Firefox 4会调度更改更改事件.
      3. Chrome 9不会发送更改事件.
      4. Safari 5会调度change事件.

您最好的选择是在表单中使用表单禁用自动填充功能,autocomplete="off"或者定期轮询以查看表单是否填充.

关于它是否在document.ready之前或之前填写的问题,它在浏览器之间甚至版本之间都有所不同.仅对于用户名/密码字段,仅在您选择用户名时填写密码字段.因此,如果您尝试附加到任何事件,您将会有一个非常混乱的代码.

你可以在这里读一读

  • 请注意自动填充和自动填充之间存在差异.OP专门指浏览器在页面加载时填写已保存的登录详细信息. (20认同)
  • 通常的 hack 是在页面的某些重要部分使用鼠标。当用户的鼠标指向按钮或类似的东西时,会触发该事件。 (2认同)

小智 59

WebKit浏览器的解决方案

来自MDN文档的:-webkit-autofill CSS伪类:

:--webkit-autofill CSS伪类匹配一个元素的值由浏览器自动填充

我们可以在所需的元素上定义一个void transition css规则.然后JS将能够挂钩事件.<input>:-webkit-autofillanimationstart

Klarna UI团队的积分.在这里看到他们的好实现:

  • 到目前为止,这是最好的解决方案!为此向列夫致敬。感谢分享 Klarna UI 的解决方案……在我找到这个之前,没有其他东西对我有用。救命稻草! (2认同)
  • 除了 CSS 规则之外,还需要这里的关键帧 https://github.com/klarna/ui/blob/v4.10.0/Field/styles.scss#L181-L189 (2认同)

Jam*_*mes 18

这适用于最新的Firefox,Chrome和Edge:

$('#email').on('blur input', function() {
    ....
});
Run Code Online (Sandbox Code Playgroud)

  • `'input'`!这对我来说是最简单的解决方案,但我只测试了自动完成,而不是自动填充. (6认同)
  • 每次按键时都会触发输入。如果您进行服务器调用,它可能会经常触发。 (2认同)

Thd*_*hdK 16

对于谷歌浏览器自动完成,这对我有用:

if ($("#textbox").is(":-webkit-autofill")) 
{    
    // the value in the input field of the form was filled in with google chrome autocomplete
}
Run Code Online (Sandbox Code Playgroud)

  • 在其他浏览器上,此方法引发错误:“语法错误,无法识别的表达式:不支持的伪:-webkit-autofill”(我在Firefox上尝试过) (4认同)
  • 不适用于 chrome 以及 2020 年,还会引发错误无法识别的表达式:不支持的伪:-webkit-autofill (2认同)

LcS*_*zar 15

为了防止有人正在寻找解决方案(就像我今天一样),要收听浏览器自动填充更改,这里是我构建的自定义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);
    };
Run Code Online (Sandbox Code Playgroud)

你可以这样称呼它:

$("#myInput").allchange(function () {
    alert("change!");
});
Run Code Online (Sandbox Code Playgroud)

  • 这看起来很像手机电池消耗者:/ (2认同)

DrN*_*Nio 11

我正在阅读很多关于这个问题的内容,并希望提供一个非常快速的解决方法来帮助我.

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

在那里inputBackgroundNormalState我的模板是'RGB(255,255,255)'.

所以基本上当浏览器应用自动完成时,它们倾向于通过在输入上应用不同的(恼人的)黄色来指示输入是自动填充的.

编辑:它适用于每个浏览器


小智 9

我也遇到了同样的问题,标签没有检测到自动填充,填充文本上移动标签的动画重叠,这个解决方案对我有用。

input:-webkit-autofill ~ label {
    top:-20px;
} 
Run Code Online (Sandbox Code Playgroud)


Buc*_*ket 7

不幸的是,我发现检查这个跨浏览器的唯一可靠方法是轮询输入.为了使其响应也听取事件.Chrome已开始隐藏javascript中的自动填充值,这需要黑客入侵.

  • 每半到三分之一的轮询(在大多数情况下不需要立即)
  • 使用JQuery触发change事件,然后在侦听change事件的函数中执行逻辑.
  • 为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);
    });
    
    Run Code Online (Sandbox Code Playgroud)


Dav*_*vid 6

有一个新的polyfill组件可以在github上解决这个问题.看看自动填充事件.只需要bower安装它和voilà,autofill按预期工作.

bower install autofill-event
Run Code Online (Sandbox Code Playgroud)


Ame*_*icA 6

有一个技巧可以了解浏览器是否填充输入(布尔值):

const inputEl = inputRef.current; // select the el with any way, here is ReactJs ref
let hasValue;
try {
  hasValue = inputRef.current.matches(':autofill');
} catch (err) {
  try {
    hasValue = inputRef.current.matches(':-webkit-autofill');
  } catch (er) {
    hasValue = false;
  }
}

// hasValue (boolean) is ready
Run Code Online (Sandbox Code Playgroud)

最后一个花括号后就hasValue可以使用了。您可以检测浏览器自动填充是否发生。


Cam*_*tin 5

我的解决方案:

change像往常一样监听事件,并在DOM内容负载下执行以下操作:

setTimeout(function() {
    $('input').each(function() {
        var elem = $(this);
        if (elem.val()) elem.change();
    })
}, 250);
Run Code Online (Sandbox Code Playgroud)

这将在用户有机会编辑所有非空字段之前触发更改事件。

  • 确实,@ RidIculous一些解决方案可以多么简单。 (3认同)
  • 但是elem.val()对于chrome中的自动填充密码字段返回空字符串:( (3认同)

zdr*_*oft 5

这是来自 Klarna UI 团队的 CSS 解决方案。在这里查看他们的良好实施资源

对我来说效果很好。

input:-webkit-autofill {
  animation-name: onAutoFillStart;
  transition: background-color 50000s ease-in-out 0s;
}
input:not(:-webkit-autofill) {
  animation-name: onAutoFillCancel;
}
Run Code Online (Sandbox Code Playgroud)