2017-10-18 108 views
0

我有一個應用程序,我需要添加一個特殊的字符,表情符號或類似的東西,每次用戶按快捷鍵Ctrl + D如何使用任何輸入的快捷方式添加特殊字符?

問題是,我使用的是磁通,並有我的網頁上有多個輸入,所以當有人增加了焦炭引入的一個輸入,它會調用一個動作,派遣到商店,他們更新視圖。

要添加此特殊字符我需要處理keyEvent並知道哪些輸入組件正在用來更新存儲中的相應屬性。

handleShortcut(evt) { 
    if (evt.keyCode === ...) { 
     MyActions.addSpecialChar(); 
     evt.preventDefault(); 
    } 
} 

這是唯一的方法嗎?我知道我可以使用document.activeElementevt.target獲取輸入,但由於輸入由商店狀態我改變不了自己的價值...任何想法控制?

** **更新

爲了讓事情更加清楚。我想使我的應用程序表現得像一個「桌面應用程序」,無論在哪個輸入我在我的應用程序是,如果我按下組合鍵,它會在該輸入中放置一個特殊的字符,這意味着它將由onChange處理。 (我不太熟悉React或JS,所以也許我問的太多..)

所以我會有一個onKeyPress在我的高階組件,將處理組合,並將觸發onChange將特殊字符添加到輸入的value屬性之後的活動輸入。

我做這一點的方法是在每個輸入設置一個onkeypress事件,將尋找組合和發送相同的行動,我的onChange但在文本中的特殊字符。

<input 
    onKeyPress={(evt)=>{ 
     /* ... Check combination ... */ 
     let text = _addSpecialChar(evt.target.value); 
     MyActions.update(text); 
    }} 
    onChange={(evt)=>{ 
     MyActions.update(evt.target.value); 
    }} 
/> 

正如我上面說,我想處理好與的onChange的組合,作爲一個正常的性格讓我沒有添加onkeypress事件上的每個輸入。這可能嗎?

+0

什麼是你的店的狀態是什麼樣子?爲什麼你不能將表情符號傳遞到你的商店狀態? –

+0

@ChaseDeAnda我可以和我做,但我想添加快捷方式,把一個表情符號,就好像一個普通的字符,無論哪個輸入,例如,如果我複製/粘貼它,我可以只使用onChange添加表情符號。我更新了我的問題... – MNV

回答

1

啊謝謝,您的更新使事情更加清晰。輸入表情符後,您是否可以嘗試手動觸發輸入上的更改事件?

handleShortcut(evt) { 
    if (evt.keyCode === ...) { 
     MyActions.addSpecialChar(); 
     evt.preventDefault(); 
     // Manually trigger on change here of the active element 
     evt.target.onchange(); 
    } 
} 

如果您需要模擬一個充滿變化的事件,你可以試試這個:

// Create a new 'change' event 
var event = new Event('change'); 

// Dispatch it. 
evt.target.dispatchEvent(event); 
+0

這正是我需要的!我唯一需要改變的是事件類型,它必須是'new Event('input',{bubbles:true})' – MNV

+0

真棒,很高興你能使用它! –

0

試試這個:

首先定義你的handleShortCut功能是這樣的:

handleShortcut(input, evt) { 
    switch(input) { 
     case 'mySpecialInput': 
     if (evt.keyCode === ...) { 
      MyActions.addSpecialChar() 
      evt.preventDefault() 
     } 
     break 
     default: 
     ... 
    } 
} 

然後,當你確定你的輸入做這樣的事情:

<input type="text" className="input" 
value={this.state.value} 
onChange={this.handleShortcut.bind(this, 'mySpecialInput')}/> 

現在你可以使用相同的handleShortcut fn在該組件中的任何地方,並且當你設置onChange函數來設置你想要傳遞的第一個值時使用綁定。EVERY TIME函數handleShortcut被調用編輯該輸入。 'evt'參數仍然通過,但現在作爲第二個參數。所以,如果你需要你的handleShortcut要注意從兩個不同的輸入特定的輸入源,然後只處理一切一個通用的方法,這樣做:

<input type="text" className="input" 
    value={this.state.value1} 
    onChange={this.handleShortcut.bind(this, 'mySpecialInput', 'value1')}/> 
<input type="text" className="input" 
    value={this.state.value2} 
    onChange={this.handleShortcut.bind(this, 'myOtherSpecialInput', 'value2')}/> 
<input type="text" className="input" 
    value={this.state.value3} 
    onChange={this.handleShortcut.bind(this, '', 'value3')}/> 

,讓您的handleShortcut功能是這個樣子:

handleShortcut(input, value, evt) { 
    switch(input) { 
     case 'mySpecialInput': 
     if (evt.keyCode === ...) { 
      MyActions.addSpecialChar() 
      evt.preventDefault() 
     } 
     break 
     case 'myOtherSpecialInput': 
     ... 
     default: 
     evt.preventDefault() 
     this.setState({[value]: this.state.value + 'my default symbol'}) 
    } 
} 

請注意,這次我傳遞了另一個名爲value的參數,這是本地狀態的屬性名稱,用作輸入的「值」。對於每種情況,我們都可以硬編碼我們想要影響的值,但是我們需要將這些信息用於「默認」通用情況。

+0

爲什麼downvote?我誤解了什麼嗎? – Dude

+0

我沒有downvote ...有趣的解決方案,我會有一個「主」功能來處理所有輸入。唯一覺得我不太喜歡的是每次渲染組件時的綁定。 – MNV

+0

我認爲,在我看來,增加靈活性的小价格。如果你真的不喜歡綁定,那麼你總是可以使你的句柄函數成爲一個箭頭函數,它接受我的示例中的'輸入'並返回另一個箭頭函數。然後,你只需要做一些類似onChange = {this.handleShortcut('mySpecialInput'))} – Dude

1

感謝@chase的答案!

我會把我如何解決我的問題的代碼,僅供將來參考。

handleShortcut(evt) { 
    if (evt.keyCode === ...) { 
     this.addSpecialChar(evt); 
     let newEvt = new Event('input', {bubbles: true}); 
     evt.target.dispatchEvent(newEvt); 
     evt.preventDefault(); 
    } 
} 

addSpecialChar(evt) { 
    let curText = evt.target.value; 
    let curPos = evt.target.selectionStart; 
    let newText = /* Add special char where you want */ 
    let newPos = curPos + 1; /* Move cursor where you want */ 
    evt.target.value = newText; 
    evt.target.selectionStart = newPos; 
} 

我與助焊劑成分的樣子:

<HighOrderComponent onKeyPress={this.handleShortcut}> 
    <input 
     value={this.state.inputVal} 
     onChange={ 
      (evt) => MyAction.updateInputVal(evt.target.value) 
     } 
    /> 
    . 
    . 
    . 
    /* Other inputs */ 
    . 
    . 
    . 
</HighOrderComponent> 
+0

使用react^15.6.0 set'newEvt.simulated = true;' https://stackoverflow.com/a/46012210/5981184 – MNV

相關問題