ページ全体でkeypressイベントをリッスンするにはどうすればよいですか?


109

関数をページ全体にバインドする方法を探しています(ユーザーがキーを押したときに、コンポーネントの関数をトリガーする必要があります)。ts

AngularJSではaを使用して簡単でしたng-keypressが、では機能しません(keypress)="handleInput($event)"

ページ全体をdivラッパーで試しましたが、うまくいかないようです。フォーカスがある場合にのみ機能します。

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

試しましたwindow:keypressか?
KarolDepka 2018

回答:


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}を追加する必要があります。コンポーネント内のどこでも呼び出します。外の建設
業者

23
これはありがとうございましたが、将来の読者に向けて準備しています。矢印キーが必要な場合は、キーを押す代わりにキーダウンを使用してください。
Troels Larsen 2017

14
escキーが必要な場合は、keyupイベントを使用してください。@TroelsLarsenに感謝
アロン・ロリンチ

@yurzui、特定のコンポーネントにこのイベントを使用するにはどうすればよいですか。ページ全体ではあり
ません

1
@yurzui function-key(F1、F2、F3、...)をどのように検出できますか?
Arpit Kumar 2017

18

ユルズイの答えは私にはうまくいきませんでした、それは別のRCバージョンかもしれません、またはそれは私の側の間違いかもしれません。いずれにせよ、Angular2 RC4のコンポーネントでこれを実行した方法は次のとおりです(現在はかなり古くなっています)。

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

3
それは同じですが、代わりの構文で、keydown代わりに使用しました。keypress
GünterZöchbauerSep

私が言ったように、おそらく私の側の間違いですが、それが私のためにそれを機能させるために必要なものです。:)
Adam

document.addEventListenerを使用する場合と比べて、これの利点は何ですか?DOMを抽象化するだけの問題ですか?
Ixonal、2016年

私ができるよりも、この記事に@Ixonal#2は、より良い説明:angularjs.blogspot.ca/2016/04/...基本的には、それはブラウザと結合しているため、それは、ない「角」の方法だし、それがテスト可能ではありません。今は大したことではないかもしれませんが、それは従うべき良いモデルです。
Adam

1
最新のドキュメントでは、@ HostListenerの使用を推奨しています。angular.io/ docs / ts / latest
guide

11

2019年にこれに追加するだけですw Angular 8

キーを押す代わりに、キーダウンを使用する必要がありました

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

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

ワーキングStacklitz


Angular 9レポート:keypressとkeydownはどちらも通常の "asdf"キーを登録しますが、F4と他のファンクションキーを取得できるのはkeydownだけです。KeypressはCTRL-Zのようないくつかのキーコンボを取得でき、keydownはそれらを個別に解釈します(CTRLキー、次にミリ秒後、Zキー)。
Anders8

4

特定のキーボードボタンを押したときにイベントを実行する場合は、@ HostListenerを使用できます。そのためには、コンポーネントのtsファイルにHostListenerをインポートする必要があります。

'@ angular / core'から{HostListener}をインポートします。
次に、コンポーネントのtsファイルの任意の場所で以下の関数を使用します。

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


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.