Bagaimana cara mendengarkan acara penekanan tombol di seluruh halaman?

109

Saya mencari cara untuk mengikat fungsi ke seluruh halaman saya (ketika pengguna menekan sebuah tombol, saya ingin itu memicu fungsi di component.ts saya)

Itu mudah di AngularJS dengan ng-keypresstetapi tidak berhasil (keypress)="handleInput($event)".

Saya mencobanya dengan pembungkus div di seluruh halaman tetapi tampaknya tidak berhasil. itu hanya bekerja jika fokusnya ada padanya.

<div (keypress)="handleInput($event)" tabindex="1">
L. penakluk
sumber
Apakah Anda mencoba window:keypress?
KarolDepka

Jawaban:

203

Saya akan menggunakan dekorator @HostListener dalam komponen Anda:

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

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

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

Ada juga opsi lain seperti:

properti tuan rumah dalam @Componentdekorator

Angular merekomendasikan penggunaan @HostListenerdekorator pada properti host 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();
  }
}
yurzui
sumber
2
Bekerja dengan baik. impor {HostListener} dari '@ angular / core' harus ditambahkan. dan memanggil bahkan di mana saja dalam komponen. Bahkan
kontraktor
23
Terima kasih untuk ini, tetapi hanya pemberitahuan untuk pembaca di masa mendatang: jika Anda memerlukan tombol panah, gunakan tombol bawah alih-alih menekan tombol.
Troels Larsen
14
Jika Anda membutuhkan esckuncinya, gunakan keyupevent. Terima kasih kepada @TroelsLarsen
Aron Lorincz
@yurzui, bagaimana saya bisa menggunakan acara ini untuk komponen tertentu. bukan di seluruh halaman
kamalav
1
@yurzui Bagaimana cara mendeteksi function-key(F1, F2, F3, ...)?
Arpit Kumar
18

Jawaban yurzui tidak berhasil untuk saya, mungkin versi RC yang berbeda, atau mungkin kesalahan di pihak saya. Bagaimanapun, inilah cara saya melakukannya dengan komponen saya di Angular2 RC4 (yang sekarang sudah cukup usang).

@Component({
    ...
    host: {
        '(document:keydown)': 'handleKeyboardEvents($event)'
    }
})
export class MyComponent {
    ...
    handleKeyboardEvents(event: KeyboardEvent) {
        this.key = event.which || event.keyCode;
    }
}
Adam
sumber
3
Itulah yang sama, hanya alternatif sintaks dan Anda digunakan keydownsebagai penggantikeypress
Günter Zöchbauer
Seperti yang saya katakan, mungkin kesalahan di pihak saya, tetapi itulah yang diperlukan untuk membuatnya berhasil bagi saya. :)
Adam
Apa manfaat dari ini vs menggunakan document.addEventListener? Apakah ini hanya masalah mengabstraksi DOM?
Ixonal
@Ixonal # 2 pada artikel ini menjelaskan lebih baik daripada yang saya bisa: angularjs.blogspot.ca/2016/04/… Pada dasarnya, ini bukan cara 'Angular', karena digabungkan dengan browser, dan tidak dapat diuji. Mungkin bukan masalah besar saat ini, tapi ini adalah model yang bagus untuk diikuti.
Adam
1
Dokumen terbaru merekomendasikan penggunaan @HostListener: angular.io/docs/ts/latest/guide/…
saschwarz
11

Hanya untuk menambahkan ini di 2019 w Angular 8,

Alih-alih menekan tombol, saya harus menggunakan tombol ke bawah

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

untuk

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

Bekerja Stacklitz

tshoemake
sumber
Laporan Angular 9: penekanan tombol dan tombol ke bawah akan mendaftarkan tombol "asdf" normal, tetapi hanya tombol ke bawah yang akan mendapatkan F4 dan tombol fungsi lainnya. Keypress bisa mendapatkan beberapa kombo kunci seperti CTRL-Z, keydown menafsirkannya secara terpisah (tombol CTRL, lalu milidetik kemudian, tombol Z).
Anders8
4

Jika Anda ingin melakukan acara apa pun pada penekanan tombol keyboard tertentu, dalam hal ini, Anda dapat menggunakan @HostListener. Untuk ini, Anda harus mengimpor HostListener di file ts komponen Anda.

impor {HostListener} dari '@ angular / core';
kemudian gunakan fungsi di bawah ini di mana saja di file ts komponen Anda.

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

Saya pikir ini melakukan pekerjaan terbaik

https://angular.io/api/platform-browser/EventManager

misalnya di app.component

constructor(private eventManager: EventManager) {
    const removeGlobalEventListener = this.eventManager.addGlobalEventListener(
      'document',
      'keypress',
      (ev) => {
        console.log('ev', ev);
      }
    );
  }
Whisher
sumber