看 anu 的源码,看到注释里面有一篇文章,说输入法的问题,正好很多年前也遇到过,虽然不是特别影响使用,但是这个思路确实不常见。
问题
首先,这个问题和框架无关,都会遇到的。为了方便,下面用 react 来说明。简单来说:
页面有一个输入框,每次输入一下,便向后端请求,获取一些相关数据。这里技术上不考虑节流情况。
假设用户输入了 abc
。那么由于触发 onChange
三次,所以请求了后端三次。分别是 a
ab
abc
。符合预期。
假设用户输入了 abc的
。那么触发 onChange
分别是 a
ab
abc
abcd
abcde
abc的
。这不符合预期。正确的请求应该是 4 次,即 a
ab
abc
abc的
。在使用输入法输入过程中,也触发 onChange
了。
这个问题来源和解决方案,见此: 中文输入法与React文本输入框的问题与解决方案
文章挺好的,但是太长了,所以 TLDR。我自己决定按照 compositionEvent
试试看。
处理代码
自己写着玩的,兼容性没有测试过,只是在 chrome firefox 最新版下没问题。
compositionEvent
输入合成事件,下文均指代输入法输入过程。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
| import React from 'react';
class App extends React.PureComponent { state = { text: "", isInputing: false };
handleCompsition = event => { const { isInputing } = this.state; const type = event.type; const value = event.target.value; console.log("handleCompsition", type, value);
if (type === "compositionstart") { this.setState({ isInputing: true }); } else if (type === "compositionupdate") { } else if (type === "compositionend") { this.setState({ isInputing: false }); this.setState({ text: value }); } else if (type === "change") { if (!isInputing) { this.setState({ text: value }); } else { } } };
handleChange = event => { console.log("handleChange"); this.handleCompsition(event); };
render () { const { text, isInputing } = this.state;
return ( <div> <p>输入状态:{isInputing ? "输入法输入中..." : "-"}</p> <p>输入内容:{text}</p> <p> 输入区域: <input onCompositionStart={this.handleCompsition} onCompositionUpdate={this.handleCompsition} onCompositionEnd={this.handleCompsition} onChange={this.handleChange} value={this.state.innerInputText} /> </p> </div> ); } }
export default App;
|
通过监听 onCompositionStart
onCompositionEnd
,即可得知当前是否在使用输入法进行输入,也就为解决问题有了思路。
这是相对复杂的情况(react 受控组件),非受控组件相对容易一些,可以参考原文。
–END–