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

Posted

技术标签:

【中文标题】如何为任何输入添加带有快捷方式的特殊字符?【英文标题】:How to add special character with shortcut to any input? 【发布时间】:2018-03-30 14:49:06 【问题描述】:

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

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

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

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

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

正如我上面所说,我想将与 onChange 的组合作为普通字符来处理,因此我不必在每个输入上都添加 onKeyPress。这可能吗?

【问题讨论】:

您的商店状态是什么样的?为什么不能将表情符号传递到您的商店状态? @ChaseDeAnda 我可以而且我可以,但是我想添加一个快捷方式来放置一个表情符号,就像一个普通字符一样,无论哪个输入,例如,我可以只使用 onChange 添加一个表情符号,如果我复制/粘贴它。我更新了我的问题... 【参考方案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);

【讨论】:

这正是我所需要的!!!我唯一需要改变的是事件类型它必须是new Event('input', bubbles: true)【参考方案2】:

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

【讨论】:

使用 react^15.6.0 set newEvt.simulated = true; ***.com/a/46012210/5981184【参考方案3】:

试试这个:

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

【讨论】:

我没有投反对票...有趣的解决方案,我将有一个“主要”功能来处理所有输入。唯一不喜欢的就是每次渲染组件时的绑定。 嗯,在我看来,增加灵活性的价格很小。如果你真的不喜欢绑定,那么你总是可以让你的句柄函数成为一个箭头函数,它从我的例子中获取“输入”并返回另一个箭头函数。然后你会做类似 onChange=this.handleShortcut('mySpecialInput'))

以上是关于如何为任何输入添加带有快捷方式的特殊字符?的主要内容,如果未能解决你的问题,请参考以下文章

如何为 FileMerge 分配快捷方式

如何为不同的键盘布局使用默认快捷键?

将 Rider 与 Unity 一起使用时如何为播放按钮分配快捷方式?

如何为快捷方式应用自定义 SiriKit 意图扩展以请求允许访问?

我在wpf中使用了自定义的控件,请问如何为自定义控件中的一个按钮设置快捷键?

如何为Gnome3添加自启动程序