通常來講,react上咱們都會用change事件去處理input的輸入,但這樣就致使一個問題,在輸入中文的時候,咱們還沒輸入完成就會觸發change事件,這樣顯然不是理想情況。
那麼,怎麼解決這個問題呢?首先,你須要瞭解3個事件,compositionstart,compositionupdate和compositionend。什麼意思呢?react
要開始輸入中文git
插入新字符github
輸入完成
下面是一段代碼,能夠copy感覺一下web
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
而後,看一下效果
chrome
能夠看到,咱們再輸入中文的過程當中,event.data爲輸入的英文值,而且連英文字符之間的分隔符也有,這樣就致使一些問題,好比咱們的input不容許輸入特殊字符,這樣咱們若是用onchange去處理的話,顯然不行。因此咱們要想辦法,在中文輸入完成以後,再處理onchange事件。瀏覽器
明白這幾個事件以後,怎麼辦呢?看這裏babel
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的方法。
代碼以下this
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地址以下,歡迎你們查看spa
react-inputcode