如何在整个页面上监听按键事件?


109

我正在寻找一种将功能绑定到我的整个页面的方法(当用户按下一个键时,我希望它在我的component.ts中触发一个功能)

使用AngularJS很容易,ng-keypress但不能使用(keypress)="handleInput($event)"

我在整个页面上使用div包装器进行了尝试,但似乎不起作用。它只有在焦点对准它时才起作用。

<div (keypress)="handleInput($event)" tabindex="1">

你试过了window:keypress吗?
KarolDepka '18

Answers:


203

我会在您的组件中使用@HostListener装饰器:

import { HostListener } from '@angular/core';

@Component({
  ...
})
export class AppComponent {

  @HostListener('document:keypress', ['$event'])
  handleKeyboardEvent(event: KeyboardEvent) { 
    this.key = event.key;
  }
}

还有其他选项,例如:

主机属性@Component装饰

Angular建议@HostListener在主机属性上使用装饰器https://angular.io/guide/styleguide#style-06-03

@Component({
  ...
  host: {
    '(document:keypress)': 'handleKeyboardEvent($event)'
  }
})
export class AppComponent {
  handleKeyboardEvent(event: KeyboardEvent) {
    console.log(event);
  }
}

renderer.listen

import { Component, Renderer2 } from '@angular/core';

@Component({
  ...
})
export class AppComponent {
  globalListenFunc: Function;

  constructor(private renderer: Renderer2) {}

  ngOnInit() {
    this.globalListenFunc = this.renderer.listen('document', 'keypress', e => {
      console.log(e);
    });
  }

  ngOnDestroy() {
    // remove listener
    this.globalListenFunc();
  }
}

Observable.fromEvent

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/fromEvent';
import { Subscription } from 'rxjs/Subscription';

@Component({
  ...
})
export class AppComponent {
  subscription: Subscription;

  ngOnInit() {
    this.subscription = Observable.fromEvent(document, 'keypress').subscribe(e => {
      console.log(e);
    })
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }
}

2
挺好的。从'@ angular / core'导入{HostListener}必须添加。甚至可以在组件中的任何地方调用。即使外面的施工方也能正常工作
gnganpath

23
感谢您这样做,但是对未来的读者来说是个小提示:如果您需要箭头键,请使用keydown而不是keypress。
Troels Larsen

14
如果需要esc密钥,请使用keyup事件。感谢@TroelsLarsen
阿隆·

@yurzui,我该如何对特定组件使用此事件。
不在

1
@yurzui如何检测function-key(F1,F2,F3,...)?
Arpit Kumar

18

yurzui的答案对我不起作用,可能是其他RC版本,或者对我而言可能是一个错误。无论哪种方式,这都是我对Angular2 RC4中的组件(现在已经过时)进行的操作。

@Component({
    ...
    host: {
        '(document:keydown)': 'handleKeyboardEvents($event)'
    }
})
export class MyComponent {
    ...
    handleKeyboardEvents(event: KeyboardEvent) {
        this.key = event.which || event.keyCode;
    }
}

3
这是一样的,只是替代语法和你使用keydown的不是keypress
冈特Zöchbauer

就像我说的那样,可能是我的错误,但这就是让它为我工作所需要的。:)
亚当

与使用document.addEventListener相比,这有什么好处?这仅仅是抽象DOM的问题吗?
Ixonal

@Ixonal#2在本文上的描述比我能描述的要好得多:angularjs.blogspot.ca/2016/04/…基本上,这不是“ Angular”方式,因为它与浏览器耦合,并且不可测试。现在也许不是什么大问题,但这是一个很好的遵循模型。
亚当

1
最新的文档建议使用@HostListener:angular.io/docs/ts/latest/guide/…–
saschwarz

11

只需在2019年Angular 8中添加此功能

而不是按键,我不得不使用按键

@HostListener('document:keypress', ['$event'])

@HostListener('document:keydown', ['$event'])

工作斯塔克利茨


Angular 9报告:按下和按下都会注册普通的“ asdf”键,但是只有按下会获得F4和其他功能键。按键可以获得一些按键组合,例如CTRL-Z,按键按下可分别解释它们(一个CTRL键,然后是毫秒后的一个Z键)。
6

4

如果要在任何特定的键盘按钮按下时执行任何事件,在这种情况下,可以使用@HostListener。为此,您必须在组件ts文件中导入HostListener。

从“ @ angular / core”导入{HostListener};
然后在组件ts文件中的任何位置使用下面的函数。

@HostListener('document:keyup', ['$event'])
  handleDeleteKeyboardEvent(event: KeyboardEvent) {
    if(event.key === 'Delete')
    {
      // remove something...
    }
  }


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.