input 组件问题

作者: shaokang 时间: September 16, 2022字数:1624

前言

记录近期遇到的一些琐碎小问题

input placeholder 在 Chrome、低版本 firefox 浏览器下不垂直居中的问题

问题复现:单独设置 placeholder 的字体大小、与 input 输入的字体大小不一样,这时会发现在 Chrome 下 placeholder 会出现偏移。
本质应该算是 Chrome 浏览器的 bug。

解决方案:

  1. 利用 margin-top、padding-top 等定位方式让其强制居中。
    不推荐,缺点:会导致其他浏览器下产生不一样的效果。

  2. 绝对定位,垂直居中。 使用 absolute 定位 + transform 使其居中。
    不推荐,缺点:发现设置后在 Safari 浏览器下鼠标只要移入输入框,placeholder 就会向下偏移。

  3. placeholder-shown + line-height。
    较好的解决方案,在 :placeholder-shown 中设置 placeholder 的字体大小,这样 Chrome 下就不会偏移。然后 :placeholder 设置 line-height 为 height 使其居中,解决低版本下 firefox 不居中的问题。

设置 input 自动聚焦

方案:页面渲染完后,使用 focus 方法。

示例:

// san
this.nextTick(() => {
    this.ref('input').focus();
});

限制 input 只能输入数字

如果是 antd 这种组件库,可以使用 getValueFromEvent 来限制输入。

示例:

// 详见 https://codesandbox.io/s/dong-tai-xiao-yan-gui-ze-antd-4-22-8-forked-hwwhpr
const phoneNoFormat = (e) => {
    return e.target.value.replace(/[^\d]/g, "");
};

<Form.Item
    {...formItemLayout}
    name="username"
    label="Name"
    rules={[
        {
        required: true,
        message: "Please input your name"
        }
    ]}
    getValueFromEvent={phoneNoFormat}
>
    <Input placeholder="Please input your name" />
</Form.Item>

MVVM 框架也可以考虑在 watch 监听中修改输入的值

示例:

// san
this.watch('value', (value: string) => {
    this.data.set('value', value.replace(/[^\d]/g, ''));
});

input clear 不触发 onBlur,并使其重新聚焦

input 组件一般都会有一个 clear 的后缀 icon,正常效果是清除后重新聚焦输入。

直接看下 antd 的设计方案:

  1. onMouseDown 中禁止默认行为,防止点击 clear 后触发 onBlur 事件。
    见:https://github.com/ant-design/ant-design/blob/master/components/input/ClearableLabeledInput.tsx#L59

  2. 清除 input 内容后,重新聚焦。
    见:https://github.com/react-component/input/blob/master/src/Input.tsx#L105