我有一个应用程序,每当用户按下快捷键 Ctrl + D 时,我需要添加一个特殊字符,表情符号或类似的东西。
问题是我使用flux并在我的页面上有几个输入,所以当有人在其中一个输入中添加一个char时,它会调用一个动作,调度到商店,然后他们更新视图。 / p>
要添加此特殊字符,我需要处理keyEvent并知道正在使用哪个输入组件来更新商店中的相应属性。
handleShortcut(evt) {
if (evt.keyCode === ...) {
MyActions.addSpecialChar();
evt.preventDefault();
}
}
这是唯一的方法吗?我知道我可以使用document.activeElement
或evt.target
来获取输入,但由于输入是由商店状态控制的,因此我无法更改其值...任何想法?
**更新**
为了让事情变得更清楚......我想让我的应用程序表现得像一个桌面应用程序",无论我在我的应用程序中输入哪个输入,如果我按下键组合它将在该输入中放置一个特殊的char,这意味着它将由onChange处理。 (我不熟悉React或JS,所以也许我问得太多了......)
所以我在我的高阶组件中有一个onKeyPress来处理组合,并在将特殊字符添加到输入的value
属性后触发活动输入上的onChange。
我实现它的方式是在每个输入上设置一个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 :(得分: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);
答案 1 :(得分: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>
答案 2 :(得分: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函数时使用bind来设置你想要传递的第一个值,每次为该输入调用函数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的参数,这是本地状态的属性名称,用作输入的“值”。对于每种情况,我们都可以硬编码我们想要影响的值,但我们需要“默认”通用案例的信息。