Як я можу прослухати подію клавіш на всій сторінці?


109

Я шукаю спосіб прив’язати функцію до всієї сторінки (коли користувач натискає клавішу, я хочу, щоб вона запустила функцію у своєму компоненті.ts)

У AngularJS було легко, ng-keypressале це не працює (keypress)="handleInput($event)".

Я спробував це з обгорткою для Div на всій сторінці, але, схоже, це не працює. він працює лише тоді, коли фокус на ньому.

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

Ви пробували window:keypress?
KarolDepka

Відповіді:


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();
  }
}

Спостерігається

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
Werking штрафу. імпорт {HostListener} з '@ angular / core' потрібно додати. і дзвонити навіть у будь-якому місці компонента. Навіть бічний кондуктор також працює добре
gnganpath

23
Дякуємо за це, але лише голова для майбутніх читачів: якщо вам потрібні клавіші зі стрілками, використовуйте клавіші замість натискання клавіш.
Тролі Ларсена

14
Якщо вам потрібен escключ, використовуйте keyupподію. Дякуємо @TroelsLarsen
Aron Lorincz

@ yurzui, як я можу використовувати цю подію для конкретного компонента.не на цілій сторінці
kamalav

1
@yurzui Як я можу виявити function-key(F1, F2, F3, ...)?
Арпіт Кумар

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
Günter Zöchbauer

Як я вже казав, напевно, помилка з мого боку, але це те, що потрібно, щоб він працював на мене. :)
Адам

Яка користь від цього порівняно з використанням document.addEventListener? Це лише питання абстрагування DOM?
Іксонал

@Ixonal №2 у цій статті описує краще, ніж я можу: angularjs.blogspot.ca/2016/04/… В основному, це не "кутовий" спосіб, оскільки він поєднується з браузером, і він не перевіряється. Можливо, зараз не велика справа, але це хороша модель, яку слід наслідувати.
Адам

1
Останні документи рекомендують використовувати @HostListener: angular.io/docs/ts/latest/guide/…
saschwarz

11

Просто до цього додати в 2019 році з кутовим 8,

замість натискання клавіші мені довелося використовувати клавіш

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

до

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

Робочий Stacklitz


Кутовий звіт 9: і натискання клавіш, і натискання клавіш реєструють звичайні клавіші "asdf", але тільки клавіш має F4 та інші функціональні клавіші. Клавіша може отримати деякі комбінації клавіш, такі як CTRL-Z, клавіш інтерпретує їх окремо (клавіша CTRL, потім мілісекунди, ключ Z).
Anders8

4

Якщо ви хочете виконати будь-яку подію на будь-якому конкретному натисканні кнопки клавіатури, у такому випадку ви можете скористатися @HostListener. Для цього вам потрібно імпортувати HostListener у файл вашого компонента.

імпортувати {HostListener} з '@ angular / core';
тоді використовуйте функцію нижче в будь-якому місці вашого компонентного файлу ts.

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


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.