input输入框在微软拼音输入法下的bug

940 阅读1分钟
  1. 问题描述:正常情况下input在微软输入法输入英文和符号都没问题,但在我们使用拼音并且有校验的情况下会出现奇怪的现象,拼音输入是一个过程,确切的说,在这个过程中,你输入的每一个字母都触发了 onChange 事件,而你输入过程中的这个产物在校验中被吃掉了,留下了一坨空字符串,所以就发生了那个神奇的现象。
  2. 关键属性:componsitonstart和componsitonend。就是当你开始使用输入法进行新的输入的时候,会触发 compositionstart ,中间过程其实也有一个函数 compositionupdate,顾名思义,输入更新时会触发它;当结束输入法输入的时候,会触发 compositionend。
  3. 解决方案:重写input组件,新增onComponsitonStart和onComponsitonEnd属性,定义一个参数lock,通过lock值去出发input的onChange动作,而lock只有在componsitonend下才有效,也就是说通过手动去判断我们的输入是否结束。(不同浏览器下componsitonstart、compositionupdate、componsitonend的执行顺序会有差异)
const RuleInput = () => {
    const [inputValue, setInputValue] = useState('');
    let lock = false;
    const inputRef = useRef();
    function handleChange(e) {
        console.log(e);
        if (e.type === 'compositionend') {
            lock = false;
            if (navigator.userAgent.indexOf('Chrome') > -1) {
                onchange(e);
            };
           return
       }
       lock = true;
    }
    const onchange = (e) => {
        console.log(lock);
        const { value } = e.target;
        if (!lock) {
            inputRef.current.value = value.replace(/[^a-zA-Z0-9\u4E00-\u9FA5]/g, '');
        }
    }
    const onchangeAntd = (e) => {
        console.log(e.target.value);
        const val = e.target.value.replace(/[^a-zA-Z0-9\u4E00-\u9FA5]/g, '');
        setInputValue(val);
    }
    
    return (
        <>
            <input
              ref={inputRef}
              type="text"
              placeholder="请输入"
              maxLength={20}
              onChange={onchange}
              onCompositionStart={handleChange}
              onCompositionEnd={handleChange}
            />
            <Input
              type="text"
              value={inputValue}
              placeholder="请输入"
              maxLength={20}
              onChange={onchangeAntd}
            />
        </>
      )
}