Angular 2+ 拦截Command+S的优雅方式

Angular 2+ elegant way to intercept Command+S

正在尝试为 Command+S 实现快捷键组合以保存表单。

我读过这个 - https://angular.io/guide/user-input,但它没有说明任何关于元或命令的内容。

尝试在表格周围添加:

<div
  (keyup.command.s)="save()"
  (keyup.command.u)="save()"
  (keyup.control.u)="save()"
  (keyup.control.s)="save()"
  (keyup.meta.u)="save()"
>

其中,只有 control.ucontrol.s 有效。

凭借 Angular 2+ 的所有强大功能和跨浏览器功能,我希望使用 (keyup...).

以某种优雅的方式处理此问题

而且肯定有很多 Angular 开发者使用 Mac :)。

我也读过 How does one capture a Mac's command key via JavaScript? and http://unixpapa.com/js/key.html 但仍然希望 Angular 优雅的解决方案而不是与特定于浏览器的东西作斗争...

UPDATE

要阻止浏览器的保存对话框打开,我们必须使用keydown 事件而不是keyup 并调用函数$event.preventDefault();。更新了以下代码:

  onKeyDown($event): void {
    // Detect platform
    if(navigator.platform.match('Mac')){
        this.handleMacKeyEvents($event);
    }
    else {
        this.handleWindowsKeyEvents($event); 
    }
  }

  handleMacKeyEvents($event) {
    // MetaKey documentation
    // https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/metaKey
    let charCode = String.fromCharCode($event.which).toLowerCase();
    if ($event.metaKey && charCode === 's') {
        // Action on Cmd + S
        $event.preventDefault();
    } 
  }

  handleWindowsKeyEvents($event) {
    let charCode = String.fromCharCode($event.which).toLowerCase();
    if ($event.ctrlKey && charCode === 's') {
        // Action on Ctrl + S
        $event.preventDefault();
    } 
  }

然后将此方法绑定到 div 中的 (keydown) 事件:

<div (keydown)="onKeyDown($event)" tabindex="0">
</div>

已更新PLUNKER DEMO


ORIGINAL ANSWER

这是一个想法,如何检测你的事件class:

  onKeyUp($event): void {
    // Detect platform
    if(navigator.platform.match('Mac')){
        this.handleMacKeyEvents($event);
    }
    else {
        this.handleWindowsKeyEvents($event); 
    }
  }

  handleMacKeyEvents($event) {
    // MetaKey documentation
    // https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/metaKey
    let charCode = String.fromCharCode($event.which).toLowerCase();
    if ($event.metaKey && charCode === 's') {
        // Action on Cmd + S
        $event.preventDefault();
    } 
  }

  handleWindowsKeyEvents($event) {
    let charCode = String.fromCharCode($event.which).toLowerCase();
    if ($event.ctrlKey && charCode === 's') {
        // Action on Ctrl + S
        $event.preventDefault();
    } 
  }

然后将此方法绑定到 div 中的 (keyup) 事件:

<div (keyup)="onKeyUp($event)" tabindex="0">
</div>

这是一个笨蛋 link: PLUNKER DEMO

全球听众,non-deprecated回答:

@HostListener('window:keydown', ['$event'])
onKeyDown(event: KeyboardEvent) {
    if ((event.metaKey || event.ctrlKey) && event.key === 's') {
        this.save();
        event.preventDefault();
    }
}
  1. preventDefault() 和 stopPropagation() 等方法对我不起作用(使用当前 Chrome),所以我不得不使用多个键:ctrl+shift+s
  2. 在我的组件中定义事件处理程序时,它仅适用于此子站点,并且仅当某些表单输入处于焦点时才有效,因此我不得不在另一个地方添加侦听器。
  3. 我压缩了多个函数,因为我不关心调用热键的环境,我想保存我的对象。
<pre>ngOnInit() { document.body.addEventListener("keydown", event => { let charCode = String.fromCharCode(event.which).toLowerCase(); switch (((navigator.platform.match('Mac') && event.metaKey) || event.ctrlKey) && event.shiftKey && charCode === 's') { case true: { this.saveArticle(); //whatever your usecase is break; } } }); }