首页 > 解决方案 > 自动填充不会触发 onChange

问题描述

我有一个登录表单,当页面打开时,Chrome 会自动填写凭据。但是,元素的onChange事件没有被触发。input

单击页面上的任意位置会使它们注册到 的value属性中input,这正是我们所需要的。我试过做event.target.click(),没有帮助。

在 onChange 我将值设置为如下状态:

this.setState({ email: event.target.value })

如果email.length === 0.

因此,即使页面显示凭据已填写,提交按钮仍然看起来被禁用。

由于单击任何地方都会注册值,因此单击提交按钮也会在提交之前注册它们。所以它完美地工作。

但这与时间无关,字段永远不会被填充。当我打开开发者控制台并检查时,值字段为空,直到我单击某处。

这里唯一的问题是该按钮看起来被禁用,因为在单击某些内容之前,电子邮件输入值是空的。有没有一个hacky解决方案?

标签: javascripthtmlreactjsdomautofill

解决方案


我偶然发现了这个问题,因为我遇到了同样的问题。不在 React 中,但问题是普遍存在的。也许这会帮助任何偶然发现这一点的人。

其他答案都没有真正回答这个问题。OP 描述的问题是 Chrome在用户与页面交互之前不会设置输入的值。这可以是单击页面,甚至可以在控制台中输入随机内容。

发生用户交互后,输入的值被设置并触发更改事件。

您甚至可以直观地看到这一点,因为自动填充文本的样式在首次呈现时是不同的,并且在交互发生后会更改输入的样式。

另外:触发点击或设置焦点或任何代码都无济于事,只有真正的人类互动。

所以轮询值不是一个解决方案,因为如果页面没有被点击,该值将保持为空。还声明您不能依赖更改事件并不是真正相关的,因为该事件在延迟设置值时正确触发的。问题在于无限期的延迟。

但是,您可以轮询 Chrome 的伪 CSS 类的存在。在 Chrome 83(2020 年 6 月)中,这些是:-internal-autofill-selected:-internal-autofill-previewed. 但是,这些确实会定期更改。此外,它们在渲染后不会直接存在。所以你应该设置一个足够的超时时间,或者轮询它。

香草 JavaScript 中的草率示例:

var input = document.getElementById('#someinput');

setTimeout(() => {
   if (input.matches(':-internal-autofill-selected')) {
      /* do something */
   }
}, 500);

此时您仍然无法获得该值,因此在这方面它仍然无法解决问题,但至少您可以根据自动填充数据的存在启用提交按钮(正如 OP 想要做的那样)。或者做一些其他视觉上的东西。


推荐阅读