Chrome 自动填充会导致文本字段标签和值的文本框发生冲突

2023-12-04

在 React 中,自动完成 Chrome 值不会立即触发 onChange 事件。因此,在页面初始加载期间,它会导致 MUI TextField Label 和实际值发生冲突。 我该如何解决这个问题?

enter image description here

尝试了多种方法,InputLabelProps 对 Value 的收缩也不起作用。https://stackoverflow.com/a/65070465/15435022

<StyledTextField
    fullWidth
    id="email"
    label="Email"
    size="medium"
    value={emailAddress}
    onChange={(e) => setEmailAddress(e.target.value)}
    error={emailError}
    InputLabelProps={{
      shrink: emailAddress != null && emailAddress != "" ? true : false,
    }}
    helperText={emailError ? "Please enter a valid email" : "Required"}
 />

尝试这个解决方案也会带来问题:const theme = createTheme({

GitHub资源:https://github.com/mui/material-ui/issues/14427#issuecomment-466054906

enter image description here


就我个人而言,我认为与仅禁用收缩或自动完成登录相比,这种果汁不值得挤压,但没有人询问我的意见,所以......

据我了解,这比我们想要的更痛苦的原因是因为它是起初旨在作为一项安全功能,通过自动完成防止密码被盗,但一旦 Chrome(等)删除了这些限制,React 的重复数据删除机制就接管了。有一些稍微更 hack-y 的解决方法不是我要建议的,但你可以决定你喜欢哪个。

为了避免这个问题,您可以为每个input's onAnimationStart事件,检查是否animationName is "mui-auto-fill",然后检查是否input has a -webkit-autofill伪类,查看浏览器是否已自动填充该字段。您还需要处理"mui-auto-fill-cancel"对于自动填写表单并且用户清除值(以重置shrink.)

例如:

const [passwordHasValue, setPasswordHasValue] = React.useState(false);

// For re-usability, I made this a function that accepts a useState set function
// and returns a handler for each input to use, since you have at least two 
// TextFields to deal with.
const makeAnimationStartHandler = (stateSetter) => (e) => {
  const autofilled = !!e.target?.matches("*:-webkit-autofill");
  if (e.animationName === "mui-auto-fill") {
    stateSetter(autofilled);
  }

  if (e.animationName === "mui-auto-fill-cancel") {
    stateSetter(autofilled);
  }
};
...

<TextField
  type="password"
  id="password"
  inputProps={{
    onAnimationStart: makeAnimationStartHandler(setPasswordHasValue)
  }}
  InputLabelProps={{
    shrink: passwordHasValue
  }}
  label="Password"
  value={password}
  onChange={(e) => {
    setPassword(e.target.value);
    ...
  }}
/>

结果on load应显示为:

example

Updatewith cancel -- 允许用户在加载自动填充后清除表单字段,并重置标签:

example with reset field

仅供参考:我做了我的makeAnimationStartHandler一个接受一个函数React.useState()setter 作为参数并返回一个实际完成工作的处理程序,因为您的示例有两个字段,我想 1) 减少代码,2) 允许您仍然单独处理每个字段的手动输入用例(如果需要)。

工作示例: https://z3vxm7.csb.app/
工作代码沙箱: https://codesandbox.io/s/autofill-and-mui-label-shrink-z3vxm7?file=/Demo.tsx

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Chrome 自动填充会导致文本字段标签和值的文本框发生冲突 的相关文章