【问题标题】:Angular 2+ elegant way to intercept Command+SAngular 2+优雅的拦截Command+S的方式
【发布时间】:2018-01-16 01:17:16
【问题描述】:

尝试实现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?http://unixpapa.com/js/key.html,但仍然希望 Angular 优雅的解决方案,而不是与特定于浏览器的东西作斗争......

【问题讨论】:

    标签: javascript angular cross-browser keyboard-shortcuts onkeyup


    【解决方案1】:

    全局监听器,不推荐使用的答案:

    @HostListener('window:keydown', ['$event'])
    onKeyDown(event: KeyboardEvent) {
        if ((event.metaKey || event.ctrlKey) && event.key === 's') {
            this.save();
            event.preventDefault();
        }
    }
    

    【讨论】:

      【解决方案2】:

      更新

      要阻止浏览器的保存对话框打开,我们必须使用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


      原始答案

      这是一个想法,如何在你的班级中检测事件:

        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>
      

      这是一个笨拙的链接:PLUNKER DEMO

      【讨论】:

      • “元”键有一个布尔值,它是mac上的Command键,它是event.metaKey
      • @KarolDepka 在 mac 你有metaKey。查看更新的答案。
      • 这是一篇关于组合键的有用文章:bennadel.com/blog/…
      • div 默认是不可聚焦的。我用输入元素进行测试。我为此创建了一个 plunk,这是链接:plnkr.co/edit/xtaTjKzPwIDXpc77ZcUj?p=preview [我正在尝试找出如何阻止保存对话框打开]
      • 我在windows上
      【解决方案3】:
      1. preventDefault() 和 stopPropagation() 等方法对我不起作用(使用当前的 Chrome),所以我不得不使用多个键:ctrl+shift+s
      2. 在我的组件中定义事件处理程序时,它仅适用于该子站点,并且仅在某些表单输入处于焦点时才有效,因此我不得不在另一个位置添加侦听器。
      3. 我压缩了多个函数,因为我不关心调用热键的环境,我想保存我的对象。
      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;
            }
          }
        });
      }
      

      【讨论】:

        猜你喜欢
        • 2016-06-18
        • 2020-04-23
        • 2018-07-08
        • 1970-01-01
        • 2016-08-14
        • 1970-01-01
        • 2023-03-13
        • 2018-09-15
        • 1970-01-01
        相关资源
        最近更新 更多