(React+Typescript) input设置快捷键, 并监听快捷键
功能是: 要在Input上支持直接按键盘设置快捷键, 设置完成后并监听这些快捷键进行对应的业务逻辑操作
创建组件ShortcutInput.tsx, 用来在输入框设置键盘快捷键
import React, { Component } from 'react'; interface ShortcutInputProps { shortcut?: string; systomShortcut?: any[]; existShortcut?: any[]; onChange?: (value: string, newShortCode: string) => void; } interface ShortcutInputState { shortcut: string; shortcutCode: string; showTip: boolean; } class ShortcutInput extends Component<ShortcutInputProps, ShortcutInputState> { private inputRef: React.RefObject<HTMLInputElement>; constructor(props) { super(props); this.state = { shortcut: props.shortcut, shortcutCode: '', showTip: false, }; this.inputRef = React.createRef(); } handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement> & { code?: string } ) => { let { key, code, keyCode } = event; event.preventDefault(); // if (['Shift', 'Control', 'Alt', 'Meta'].includes(key)) { // return; // } //与系统快捷键有冲突,请重新更换设置 if(this.props.systomShortcut.includes(key)) { WindowAPI.showWarningDialog("与系统快捷键有冲突,请重新更换设置"); return; } //与已设置的快捷键有冲突,请重新更换设置 if(this.props.existShortcut.includes(key)) { WindowAPI.showWarningDialog("与已设置的快捷键有冲突,请重新更换设置"); return; } // 有重复的输入键 const existingKeys = this.state.shortcut.split('+'); if (existingKeys.includes(key)) { return; } //中文输入时取code的值 if (key.toLowerCase() === 'process' && code?.startsWith('Key')) { key = code[3]; // KeyE -> E } if(key) { const newShortcut = `${this.state.shortcut.length > 0 ? `${this.state.shortcut}+` : ''}${key.toUpperCase()}`; const newShortCode = `${this.state.shortcutCode.length > 0 ? `${this.state.shortcutCode}+` : ''}${keyCode}`; this.setState({ shortcut: newShortcut, shortcutCode: newShortCode}, () => { this.props.onChange && this.props.onChange(newShortcut, newShortCode); }); } }; onClear = () => { this.setState({shortcut: '', shortcutCode: ''}, () => { this.props.onChange && this.props.onChange('', ''); }) } render() { const {showTip} = this.state; return ( <div> <Input ref={this.inputRef} value={this.state.shortcut} clearable={true} onKeydown={this.handleKeyDown} onClear={this.onClear} onMouseover={() => this.setState({showTip: true})} onMouseout={() => this.setState({showTip: false})} /> {showTip && <span style={{color: "blue", fontSize: '12px'}}>直接按键盘进行设置</span>} </div> ); } } export default ShortcutInput;
使用方式:
let systomShortcut = ['F5']; existShortcut = ['F1', 'F2'] return <ShortcutInput shortcut={value} systomShortcut={systomShortcut} existShortcut={existShortcut} onChange={(value, code) => { console.log('值改变', value, code); //可以将这些值存起来, 例如: sessionStorage.setItem("kjj",JSON.stringify(value)) }} />
这样就可以设置了
下面是监听快捷键的方式:
写一个管理快捷键的工具类 ShortcutManager:
export class ShortcutManager { private static instance: ShortcutManager; private shortcuts: Map<string, () => void> = new Map(); private constructor() {} public static getInstance(): ShortcutManager { if (!this.instance) { this.instance = new ShortcutManager(); } return this.instance; } public registerShortcut(keyCombination: string, callback: () => void): void { const normalizedKey = this.normalizeKeyCombination(keyCombination); const handler = (event: KeyboardEvent) => { const pressedKeys = this.getPressedKeys(event); const normalizedPressed = this.normalizeKeyCombination(pressedKeys.join('+')); if (normalizedPressed === normalizedKey) { event.preventDefault(); callback(); } }; window.addEventListener('keydown', handler); this.shortcuts.set(normalizedKey, () => window.removeEventListener('keydown', handler)); } private normalizeKeyCombination(keys: string): string { return keys.split('+').sort().join('+').toUpperCase(); } private getPressedKeys(event: KeyboardEvent): string[] { const keys: string[] = []; if (event.ctrlKey) keys.push('Ctrl'); if (event.shiftKey) keys.push('Shift'); if (event.altKey) keys.push('Alt'); const key = event.key || ''; if (key) { keys.push(key); } return keys; } }
ShortcutManager使用方式:
在页面初始化时以及更改或设置快捷键后调用监听
ShortcutManager.getInstance().registerShortcut(shortcut, () => { console.log(`快捷键 ${shortcut} 被触发`); // 在此添加具体业务逻辑,例如调用某个方法或跳转页面 });