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

标签 html css reactjs google-chrome material-ui

在 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(等) al.) 取消了限制,React 的重复数据删除机制接管了。有一些slightly more hack-y work-arounds比我要建议的要多,但你可以决定你喜欢哪个。

为了避免这个问题,您可以向每个 inputonAnimationStart 事件添加一个处理程序,检查 animationName 是否为 “mui-auto-fill”,然后检查输入是否有 -webkit-autofill pseudo class ,查看浏览器是否已自动填充该字段。您还需要处理“mui-auto-fill-cancel”情况,用于自动填充表单并且用户清除值(以重置shr​​ink)的情况>.)

例如:

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);
    ...
  }}
/>

加载时的结果应显示为:

example

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

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

关于html - Chrome 自动填充会导致文本字段标签和值的文本框发生冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76830737/

相关文章:

html - 如何使 div 与父级相匹配

html - div 的背景 url

html - CSS 在网站加载时失去效果

reactjs - 语义-ui-react 中的 Center Menu.Item

html - 如何设置部分伪元素内容 : "..." 的样式

javascript - codepen 中的 photoswipe.js 空白渲染

CSS 剪辑 : unset; on Safari

html - 为什么是 :hover css is not trigged in button tag?(使用 Firefox)

reactjs - React Redux 将计算存储在reducer 或action-creator 中?

javascript - react sibling 的通信,只能访问 parent