一般来说,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" id="test" 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 id="data"></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" id="test" 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" id="test" 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

最新文章

  1. BackgroundWorker学习
  2. 翻译《Writing Idiomatic Python》(三):变量、字符串、列表
  3. Swift学习(四)常量&amp;变量&amp;基础数据类型
  4. mr的logs的查看
  5. [LeetCode][Python]Integer to Roman
  6. 【Oracle】number类型保留小数位
  7. kettle 分组
  8. 【LookLook文档】通过less 定制自己的Bootstrap 样式
  9. rocketmq在linux搭建双master遇到的坑
  10. 《算法竞赛入门经典》刘汝佳 C语言部分(前四章)“注解与习题” 之思索 -&lt;1&gt;
  11. DG备库无法接受主库归档日志之密码文件
  12. Web安全0002 - SQL注入 - 注入流程
  13. mysql设置不区分大小写
  14. chrome 获得点击按钮时的事件
  15. [转]DWZ表单验证规则一览表(留着自己用)
  16. 使用数组初始化list
  17. dispaly:-webkit-box 布局中的坑
  18. Apache Phoenix基本操作-2
  19. ubuntu上通用解压方式
  20. 【线段树合并】bzoj3545: [ONTAK2010]Peaks

热门文章

  1. 完全用 Linux 工作
  2. (转)国内外优秀的Web前端工程师
  3. (78)zabbix值缓存(value cache)说明
  4. (76)zabbix_agentd.conf配置文件详解
  5. inotifywait实时监控文件目录
  6. 数据存储之json文件处理和csv文件处理
  7. 大数运算:HDU-1042-N!(附N!位数的计算)
  8. wcf第三方客户端与wcf服务之间调用入门
  9. Hive UDTF开发指南
  10. 菜鸟学Linux - Linux文件属性