关于input框ios输入中文拼音触发change事件的问题

7,643 阅读2分钟

在React项目研发的过程中遇到一个输入框问题,ios手机在输入中文拼音时在未选择指定汉字时会触发change事件,导致input文字累加,今天抽出时间来记录一下这个问题。

先看下问题的演示:

(用到了Ant Design Mobile库中的组件)

 <InputItem
        className='input'
        ref={el => this.inputRef = el}
         onChange={
            (val) => {
                this.setState({
                    inputValue: val
                })
            }
        }
        value={this.state.inputValue}
        placeholder={this.state.placeholder}>
        <Button type="primary" inline size="small" disabled={this.state.inputValue.length == 0}
                onClick={this.submitComments.bind(this)}>发 送</Button>
    </InputItem>

翻了几篇博客之后借鉴了连接作者的原话:blog.csdn.net/qq119422291…

原因:在input的onChange中监听到input中输入的值的时候进行了正则的判断,而输入中文的拼音时候也会走onChange这个方法,到这个方法做正则的替换时候不知道现在输入的是拼音,直接当成字母来处理了,就出现了Ios全键盘输入拼音时候还没有选择汉字拼音就直接转化成了字母。

所以解决办法要从compositionstart+compositionend+input三个方法入手,之前并没有了解过前两个方法的时候,看了多数文章大同小异都是用变量来判断是中文非直接输入

  • compositionstart:非直接的文字输入时(键盘输入中文的拼音)

  • compositionend:直接输入文字后(键盘选择真实的汉字)

  • input:输入内容(输入任何东西)

注:compositionend的调用会在input之后,所以在实现的时候加个延迟

 render() {
    let inputFlag = false;(在render 下面声明一个变量)
    return (<div>
    <InputItem
            className='input'
            ref={el => this.inputRef = el}
            onCompositionStart={async () => {
                inputFlag = false;
            }}
            onCompositionEnd={async () => {
                inputFlag = true;
            }}
            onInput={() => {
                setTimeout(async () => {
                    if (inputFlag) {//输入的是拼音就不回调输入的内容
                        await this.setState({
                            inputValue: this.state.inputValue
                    })
                }
            }, 100)
        }}
        onChange={
            async (val) => {
                if (inputFlag) return;
                await this.setState({inputValue: val})
            }
        }
        value={this.state.inputValue}
        placeholder={this.state.placeholder}>
        <Button type="primary" inline size="small" disabled={this.state.inputValue.length == 0}
                onClick={this.submitComments.bind(this)}>发 送</Button>
    </InputItem>
  </div>)

这样就可以有效的解决ios输入中文拼音叠加的问题了