如何为任何输入添加带快捷方式的特殊字符?

时间:2017-10-18 16:36:12

标签: javascript reactjs reactjs-flux

我有一个应用程序,每当用户按下快捷键 Ctrl + D 时,我需要添加一个特殊字符,表情符号或类似的东西。

问题是我使用flux并在我的页面上有几个输入,所以当有人在其中一个输入中添加一个char时,它会调用一个动作,调度到商店,然后他们更新视图。 / p>

要添加此特殊字符,我需要处理keyEvent并知道正在使用哪个输入组件来更新商店中的相应属性。

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

这是唯一的方法吗?我知道我可以使用document.activeElementevt.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。这可能吗?

3 个答案:

答案 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的参数,这是本地状态的属性名称,用作输入的“值”。对于每种情况,我们都可以硬编码我们想要影响的值,但我们需要“默认”通用案例的信息。

相关问题