136 votes

Comment puis-je écouter l'événement de pression sur le clavier sur toute la page ?

Je cherche un moyen de lier une fonction à l'ensemble de ma page (lorsqu'un utilisateur appuie sur une touche, je veux que cela déclenche une fonction dans mon fichier component.ts).

C'était facile dans AngularJS avec une ng-keypress mais il ne fonctionne pas avec (keypress)="handleInput($event)" .

J'ai essayé avec un div wrapper sur toute la page mais ça ne semble pas fonctionner. Il ne fonctionne que lorsque le focus est sur lui.

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

0 votes

Avez-vous essayé window:keypress ?

241voto

yurzui Points 85802

J'utiliserais @HostListener dans votre composant :

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

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

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

Il y a aussi d'autres options comme :

propriété de l'hôte sur @Component décorateur

Angular recommande d'utiliser @HostListener décorateur sur la propriété de l'hôte 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 votes

Werking fine. import {HostListener } from '@angular/core' have to add. and call even anywhere in component. Même en dehors du contructeur, cela fonctionne bien.

29 votes

Merci pour cet article, mais juste un avertissement pour les futurs lecteurs : si vous avez besoin des touches fléchées, utilisez keydown au lieu de keypress.

15 votes

Si vous avez besoin de la esc utilisez keyup événement. Merci à @TroelsLarsen

21voto

Adam Points 2834

La réponse de yurzui n'a pas fonctionné pour moi, il se peut que ce soit une version RC différente, ou une erreur de ma part. Quoi qu'il en soit, voici comment j'ai procédé avec mon composant dans Angular2 RC4 (qui est maintenant assez obsolète).

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

3 votes

C'est la même chose, juste une syntaxe alternative et vous avez utilisé keydown au lieu de keypress

0 votes

Comme je l'ai dit, c'est probablement une erreur de ma part, mais c'est ce qu'il a fallu pour que ça marche pour moi :)

0 votes

Quel serait l'avantage de cette méthode par rapport à l'utilisation de document.addEventListener ? S'agit-il simplement d'une question d'abstraction du DOM ?

17voto

tshoemake Points 777

Juste pour ajouter à cela en 2019 w Angular 8,

au lieu de keypress, j'ai dû utiliser keydown

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

à

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

Travail Stacklitz

0 votes

Rapport Angular 9 : keypress et keydown enregistrent tous deux les touches "asdf" normales, mais seul keydown obtient F4 et d'autres touches de fonction. Keypress pourrait obtenir certaines combinaisons de touches comme CTRL-Z, keydown les interprète séparément (une touche CTRL, puis quelques millisecondes plus tard, une touche Z).

5voto

Prabhat Maurya Points 268

Si vous voulez exécuter un événement lors de la pression d'un bouton spécifique du clavier, dans ce cas, vous pouvez utiliser @HostListener. Pour cela, vous devez importer HostListener dans le fichier ts de votre composant.

import { HostListener } de '@angular/core' ;
puis utilisez la fonction ci-dessous n'importe où dans le fichier ts de votre composant.

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

1voto

Whisher Points 1853

Je pense que ceci fait le meilleur travail

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

pour l'exemple dans app.component

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

2 votes

addGlobalEventListener est @deprecated - N'est plus utilisé dans le code Ivy. Sera supprimé dans la version 14.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X