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

Javascript 如何向任何输入添加带有快捷方式的特殊字符?,javascript,reactjs,reactjs-flux,Javascript,Reactjs,Reactjs Flux,我有一个应用程序,每次用户按快捷键Ctrl+D时,我都需要添加一个特殊字符、表情符号或类似的东西 问题是我使用的是flux,页面上有几个输入,所以当有人在其中一个输入中添加一个字符时,它会调用一个操作,分派到存储,然后更新视图 要添加这个特殊的字符,我需要处理keyEvent并知道哪个输入组件用于更新存储中的相应属性 handleShortcut(evt) { if (evt.keyCode === ...) { MyActions.addSpecialChar();

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

问题是我使用的是flux,页面上有几个输入,所以当有人在其中一个输入中添加一个字符时,它会调用一个操作,分派到存储,然后更新视图

要添加这个特殊的字符,我需要处理keyEvent并知道哪个输入组件用于更新存储中的相应属性

handleShortcut(evt) {
    if (evt.keyCode === ...) {
        MyActions.addSpecialChar();
        evt.preventDefault();
    }
}
这是唯一的办法吗?我知道我可以使用
document.activeElement
evt.target
获取输入,但由于输入由存储状态控制,我无法更改其值。。。有什么想法吗

**更新**

为了让事情更清楚。。。我想让我的应用程序表现得像一个“桌面应用程序”,无论我在我的应用程序中的哪个输入,如果我按下组合键,它将在该输入中放入一个特殊字符,这意味着,它将由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);
    }}
/>
{
/*…检查组合*/
让text=\u addSpecialChar(evt.target.value);
MyActions.update(文本);
}}
onChange={(evt)=>{
MyActions.update(evt.target.value);
}}
/>
正如我在上面所说的,我希望将onChange作为一个普通字符处理组合,这样就不必在每个输入上添加onKeyPress。这可能吗?

试试这个:

首先定义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(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'})
    }   
}
然后定义输入时,执行以下操作:

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

尝试以下方法:

首先定义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(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'})
    }   
}
然后定义输入时,执行以下操作:

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

啊,谢谢,您的更新让事情变得更清楚了。输入表情符号后,是否可以尝试手动触发输入上的更改事件

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);

啊,谢谢,你的更新让事情更清楚了。输入表情符号后,是否可以尝试手动触发输入上的更改事件

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);

谢谢@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>

MyAction.updateInputVal(evt.target.value)
}
/>
.
.
.
/*其他投入*/
.
.
.

谢谢@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>

MyAction.updateInputVal(evt.target.value)
}
/>
.
.
.
/*其他投入*/
.
.
.

您的门店状态如何?为什么你不能将表情符号传递到你的商店状态?@ChaseDeAnda我可以,我也可以,但是我想添加快捷方式,使表情符号看起来像普通字符一样,不管输入什么,例如,如果我复制/粘贴表情符号,我只能使用一次更改来添加它。我更新了我的问题…你的商店状态是什么样的?为什么你不能将表情符号传递到你的商店状态?@ChaseDeAnda我可以,我也可以,但是我想添加快捷方式,使表情符号看起来像普通字符一样,不管输入什么,例如,如果我复制/粘贴表情符号,我只能使用一次更改来添加它。我更新了我的问题…我没有投反对票。。。有趣的解决方案是,我有一个“main”函数来处理所有输入。我唯一不喜欢的是每次渲染组件时的绑定。嗯,在我看来,增加灵活性的价格很低。如果您真的不喜欢绑定,那么您可以将handle函数设置为arrow函数,该函数从我的示例中获取“输入”,并返回另一个arrow函数。然后你会做一些类似onChange={this.handleShortcut('mySpecialInput')}的事情。我没有投反对票。。。有趣的解决方案是,我有一个“main”函数来处理所有输入。我唯一不喜欢的是每次渲染组件时的绑定。嗯,在我看来,增加灵活性的价格很低。如果您真的不喜欢绑定,那么您可以将handle函数设置为arrow函数,该函数从我的示例中获取“输入”,并返回另一个arrow函数。然后你只需要做一些像onChange={this.handleShortcut('mySpecialInput'))}这正是我需要的!!!我唯一需要更改的是事件类型,它必须是
newevent('input',{bubbles:true})
这正是我需要的!!!我唯一需要更改的是事件类型,它必须是
newevent('input',{bubbles:true})
才能使用react^15.6.0 set
newEvt.simulated=true使用react ^15.6.0集合
newEvt.simulated=true