我在 React 应用程序中使用 Material-UI TextField 组件作为登录表单。当浏览器(例如 Chrome)将保存的凭据自动填充到输入字段时,我面临的问题就会发生。值填写正确,但浮动标签保留在输入字段中,导致标签和值重叠并且不可读。
自动填充输入时,标签应浮动到顶部,但只有当我手动单击输入字段时才会发生这种情况。在此之前,标签将保留在字段内,与值重叠。
我的问题: 当浏览器自动填充输入字段时,如何自动将标签浮动到顶部,而不需要用户交互?
我尝试使用 inputRef 并手动触发焦点和模糊事件,但没有成功。 我也尝试过使用 MutationObserver 通过监控值的变化来检测自动填充,但仍然没有解决标签自动上移的问题。
我在我的应用程序中使用这个组件:
export const AutoFillAwareTextField = ({ onChange, inputProps, InputLabelProps, ...rest }: TextFieldProps) => {
const [fieldHasValue, setFieldHasValue] = useState(false);
const makeAnimationStartHandler =
(stateSetter: React.Dispatch<React.SetStateAction<boolean>>) =>
(e: React.AnimationEvent<HTMLInputElement | HTMLTextAreaElement>) => {
const autofilledBrowser = Boolean((e.target as any)?.matches('*:-webkit-autofill'));
const autofilled = autofilledBrowser || (exists(rest.value) && !isEmptyString(rest.value as any));
if (e.animationName === 'mui-auto-fill' || e.animationName === 'mui-auto-fill-cancel') {
stateSetter(autofilled);
}
};
const _onChange = useCallback(
(e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
onChange?.(e.target.value as any);
setFieldHasValue(e.target.value !== '');
},
[onChange],
);
return (
<TextField
inputProps={{
onAnimationStart: makeAnimationStartHandler(setFieldHasValue),
...inputProps,
}}
InputLabelProps={{
shrink: fieldHasValue,
...InputLabelProps,
}}
onChange={_onChange}
{...rest}
/>
);
};
它基本上有一个动画监听器,并包装
onChange
函数来存储指示输入是否有内容的状态,并基于此缩小 InputLabel
。