input 组合事件
compositionEvent 组合事件是拆分了不同步骤的事件的组合,是由 compositionStart,compositionUpdate 和 compositionEnd三个事件组合而成。
Start 和 End 事件只执行一次,Update 会执行多次。
输入前,会触发 Start 和 Update 事件;没有选中中文之前,会一直触发 Update 事件;选中文字后,会触发 End 事件;一个组合事件完成,以此循环。
compositionstart
输入法编辑器开始新的输入合成时会触发 compositionstart事件。
例如:当用户使用拼音输入法开始输入汉字时,这个事件就会被触发。
compositionupdate
字符被输入到一段文字的时候(这些可见字符的输入可能需要一连串的键盘操作、语音识别或者点击输入法的备选词)会触发 compositionupdate 事件。
compositionend
当文本段落的组成完成或取消时, compositionend 事件将被触发。
例子
简单使用
<input
placeholder="Basic usage"
onChange={e => console.log('onchange', e.target.value)}
onCompositionStart={e => console.log('onCompositionStart', e.target.value)}
onCompositionUpdate={e => console.log('onCompositionUpdate', e.target.value)}
onCompositionEnd={e => console.log('onCompositionEnd', e.target.value)}
/>
输入英文'suzhou', 只会触发onChange事件:

输入中文‘苏州’,触发事件如下:

输入中文‘苏州’后, 删除‘州’,只会触发onChange事件:

监听输入的中文字符变化,如何实现?
let isOnComposition = false
function handleComposition(e) {
console.log(e.type, e.target.value)
if (e.type === 'compositionend') {
isOnComposition = false
if (!isOnComposition) {
onChange(e);
}
} else {
isOnComposition = true
}
}
function onChange(e) {
if (!isOnComposition) {
console.log('onChange', e.target.value)
}
}
ReactDOM.render(
<input
placeholder="Basic usage"
onChange={onChange}
onCompositionStart={handleComposition}
onCompositionUpdate={handleComposition}
onCompositionEnd={handleComposition}
/>, mountNode);
输入英文‘suzhou’,只会触发 onchange 事件:

输入中文‘苏州’,然后删除‘州’,触发事件如下:

input 在手机端触发软键盘的表现
输入框聚焦(触发 focus 事件)后,会弹出软键盘, 表现如下:
IOS 软键盘弹起表现
输入框获取焦点后,键盘弹起,页面(webview)没有被压缩,页面可使区域高度(height)还是原高度,只是页面(webview)整体往上滚了,且最大滚动高度(scrollTop)为软键盘高度。
Android 软键盘弹起表现
输入框获取焦点后,键盘弹起,页面(webview)高度会发生改变,高度为可视区高度(原高度减去软键盘高度),除了因为页面内容被撑开可以产生滚动,webview 本身不能滚动。
IOS 软键盘收起表现
触发软键盘上的“收起”按钮键盘或者输入框以外的页面区域时,输入框失去焦点,软键盘收起,会触发 blur事件。
Android 软键盘收起表现
触发输入框以外的区域时,输入框失去焦点,软键盘收起。但是,触发键盘上的收起按钮键盘时,软键盘收起,输入框不会失去焦点,不会触发 blur事件。
综合上面键盘弹起和收起在 IOS 和 Android 上的不同表现,需要分开处理来监听软键盘的弹起和收起:
- 在
IOS上,监听输入框的focus事件来获知软键盘弹起,监听输入框的blur事件获知软键盘收起。 - 在
Android上,监听webview高度会变化,高度变小获知软键盘弹起,否则软键盘收起。
