react输入框输入中文bug

react

一般来说,react上我们都会用change事件去处理input的输入,但这样就导致一个问题,在输入中文的时候,我们还没输入完成就会触发change事件,这样显然不是理想状况。

那么,怎么解决这个问题呢?首先,你需要了解3个事件,compositionstart,compositionupdate和compositionend。什么意思呢?

compositionstart

要开始输入中文

compositionupdate

插入新字符

compositionend

输入完成

下面是一段代码,可以copy感受一下

    class App extends React.Component {

constructor(props) {

super(props)

}

compositionstart(event) {

console.log('开始输入', event.data);

}

compositionupdate(event) {

document.getElementById('data').innerHTML = event.data;

console.log('正在输入的数据', event.data);

}

compositionend(event) {

console.log('结束输入', event.data);

}

changeEvent() {

console.log('改变');

}

render() {

return (

<div style={{padding:"50px"}}>

<input type="text" onChange={this.changeEvent.bind(this)}

onCompositionStart={this.compositionstart.bind(this)}

onCompositionUpdate={this.compositionupdate.bind(this)}

onCompositionEnd={this.compositionend.bind(this)}/>

<span style={{marginLeft:"50px"}}>输入的数据为 <span ></span></span>

</div>

)

}

}

window.onload = function () {

ReactDOM.render(

<App/>,

document.getElementById('root')

)

}

需要注意的是,要引入react和babel

<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>

然后,看一下效果

可以看到,我们再输入中文的过程中,event.data为输入的英文值,并且连英文字符之间的分隔符也有,这样就导致一些问题,比如我们的input不允许输入特殊字符,这样我们如果用onchange去处理的话,显然不行。所以我们要想办法,在中文输入完成之后,再处理onchange事件。

明白这几个事件之后,怎么办呢?看这里

var isOnComposition = true;

class App extends React.Component {

constructor(props) {

super(props)

}

handleComposition(e) {

console.log('type', e.type)

if (e.type === 'compositionend') {

// composition is end

isOnComposition = false

} else {

// in composition

isOnComposition = true

}

}

changeEvent() {

if (!isOnComposition) {

console.log('改变');

}

}

render() {

return (

<div>

<input type="text" onChange={this.changeEvent.bind(this)}

onCompositionStart={this.handleComposition.bind(this)}

onCompositionUpdate={this.handleComposition.bind(this)}

onCompositionEnd={this.handleComposition.bind(this)}/>

</div>

)

}

}

window.onload = function () {

ReactDOM.render(

<App/>,

document.getElementById('root')

)

}

这段代码,简洁明了,我们定义一个中间变量isOncomposition,默认为true,当触发compositionend事件时,我们把它赋为false,这样change事件就会执行。在除chrome之外的其他浏览器中,compositionend事件是先于change事件触发的,所以上述代码可以很好的运行。

而在chrome浏览器中,change方法会先于compositionend事件执行,这样的话,我们的change在执行时,isOncomposition永远都是true。

怎么办呢?就是在compositionend中加一个判断!isOnComposition && isChrome,当chrome浏览器时,会在compositionend结束,执行change的方法。

代码如下

var isOnComposition = false;

const isChrome = !!window.chrome && !!window.chrome.webstore

class App extends React.Component {

constructor(props) {

super(props)

}

handleComposition(e) {

console.log('type', e.type)

if (e.type === 'compositionend') {

// composition is end

isOnComposition = false

if (!isOnComposition && isChrome) {

// fire onChange

this.changeEvent(e);

}

} else {

// in composition

isOnComposition = true

}

}

changeEvent() {

if (!isOnComposition) {

console.log('改变');

}

}

render() {

return (

<div>

<input type="text" onChange={this.changeEvent.bind(this)}

onCompositionStart={this.handleComposition.bind(this)}

onCompositionUpdate={this.handleComposition.bind(this)}

onCompositionEnd={this.handleComposition.bind(this)}/>

</div>

)

}

}

window.onload = function () {

ReactDOM.render(

<App/>,

document.getElementById('root')

)

}

github地址如下,欢迎大家查看

react-input

以上是 react输入框输入中文bug 的全部内容, 来源链接: utcz.com/z/381914.html

回到顶部