我有一个登录表单,当页面打开时,Chrome会自动填写凭据。但是,没有触发onChange
个元素的input
事件。
点击页面上的任意位置,即可将它们注册到value
的{{1}}属性中,这正是我们所需要的。我尝试做input
,但没有帮助。
在onChange中,将值设置为如下状态:
event.target.click()
如果this.setState({ email: event.target.value })
,则提交按钮被禁用。
因此,即使页面显示凭据已满,“提交”按钮仍然被禁用。
由于单击任意位置都会注册值,因此单击提交按钮也会在提交之前注册它们。因此,它运作完美。
尽管与时间无关,但从未填充字段。当我打开开发者控制台并检查时,值字段为空,直到单击某处。
这里唯一的问题是,该按钮看上去已禁用,因为在单击某些内容之前,电子邮件输入值是空的。是否有针对性的解决方案?
答案 0 :(得分:2)
答案是要么在表单中使用autocomplete =“ off”禁用表单的自动完成功能,要么定期轮询以查看其是否已填充。
问题是自动填充由不同的浏览器进行不同的处理。 有些派遣变更事件,有些则没有。所以几乎是不可能的 挂钩事件,该事件在浏览器自动完成时触发 输入字段。
更改不同浏览器的事件触发:
对于用户名/密码字段:
- Firefox 4,IE 7和IE 8不会调度更改事件。
- Safari 5和Chrome 9确实分发了更改事件。
对于其他表单字段:
- IE 7和IE 8不会调度更改事件。
- 当用户从建议列表中选择一个值并跳出字段时,Firefox 4确实调度了更改更改事件。
- Chrome 9不会调度更改事件。
- Safari 5确实调度了更改事件。
您最好的选择是使用禁用表单自动完成功能
autocomplete="off"
在您的表单中或定期轮询以查看 如果已填充。关于是否在文档上或文档之前填写的问题 同样,它因浏览器而异,甚至版本也不同。 仅在您选择用户名密码时才用于用户名/密码字段 字段已填写。因此,如果您总共将有一个非常凌乱的代码 尝试附加到任何事件。
您可以对此进行很好的阅读 HERE
看看这个线程:Detecting Browser Autofill
答案 1 :(得分:2)
我偶然发现了这个问题,因为我遇到了同样的问题。不是在React中,而是普遍存在的问题。也许这会帮助那些偶然发现此问题的人。
没有其他答案可以真正回答问题。 OP所描述的问题是,Chrome不会设置输入的值,除非用户与页面进行了交互。这可以单击页面,甚至可以在控制台中键入随机内容。
发生用户交互后,将设置输入的值并触发更改事件。
您甚至可以从视觉上看到这一点,因为自动填充文本的样式在首次显示时是不同的,并且在进行交互后会更改输入的样式。
此外:触发点击或设置焦点或代码中的任何内容都无济于事,只有真正的人机交互。
因此,轮询该值不是解决方案,因为如果未单击页面,则该值将保持为空。还指出您不能依赖change事件并没有真正意义,因为在延迟设置值后会正确触发事件 。问题是无限期的延迟。
不过,您可以轮询是否存在Chrome的伪CSS类。在Chrome 83(2020年六月)中,它们是:-internal-autofill-selected
和:-internal-autofill-previewed
。但是,这些确实会定期更改。同样,它们在渲染后不直接存在。因此,您应该设置足够的超时时间或对其进行轮询。
原始JavaScript中的草率示例:
var input = document.getElementById('#someinput');
setTimeout(() => {
if (input.matches(':-internal-autofill-selected')) {
/* do something */
}
}, 500);
此时您仍然无法获得该值,因此就此而言,它仍然无法解决问题,但是至少您可以基于自动填充数据的存在启用提交按钮(因为OP希望做)。或做一些其他视觉操作。
答案 2 :(得分:1)
event.target.click()
将“模拟”一次点击并触发onClick()事件,但并不像浏览器窗口中的实际点击那样。
您是否已尝试使用focus()代替click()(或除了click()之外)?您可以尝试将焦点放在输入元素上,然后检查是否设置了该值。如果可行,您可以在焦点和点击上添加this.setState({ email: event.target.value })
。
答案 3 :(得分:0)
我在这里创建了一个示例应用程序 https://codesandbox.io/s/ynkvmv16v
这可以解决您的问题吗?
答案 4 :(得分:0)
无需触发点击事件,我认为,如果像这样在email
中设置componentDidMount
状态,那就更好了
this.setState({ email: document.getElementById('email').value })
因此,一旦调用componentDidMount()
,您将得到Chrome浏览器填充的电子邮件并更新state
,然后呈现“提交”按钮并将其启用。
您可以在此link
上了解有关React生命周期的更多信息答案 5 :(得分:0)
使用oninput代替onchange可以解决问题
答案 6 :(得分:0)
如果通过自动填充在表单中填写数据,而您尝试直接提交表单,则像 Firefox 这样的浏览器不会获取输入数据,因为它不在该输入状态。
但如果您使用基于类的组件,我们可以在 useEffect 钩子或 componentDidMount 中解决它。
useEffect(() => {
setUserName(document.getElementById('username').value);
}, [])
setUserName 这里是状态集方法,替换成你的。 使用输入字段的 ID 更改用户名。