전체 페이지에서 키 누르기 이벤트를 수신하려면 어떻게해야합니까?


109

내 전체 페이지에 함수를 바인딩하는 방법을 찾고 있습니다 (사용자가 키를 누를 때 내 구성 요소에서 함수를 트리거하고 싶습니다).

AngularJS에서 a를 사용하는 것은 쉬웠 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();
  }
}

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
이것에 대해 감사하지만, 미래의 독자들을 위해 미리 알려드립니다. 화살표 키가 필요하다면 키 누르기 대신 키 다운을 사용하세요.
Troels Larsen

14
esc키 가 필요한 경우 keyup이벤트를 사용하십시오 . @TroelsLarsen에 감사
아론 로린 츠에게

@yurzui, 어떻게 전체 페이지에 특정 component.not이 이벤트 사용할 수 있습니다
kamalav

1
@yurzui function-key(F1, F2, F3, ...)를 어떻게 감지 합니까?
Arpit 쿠마

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'방식이 아닙니다. 지금 당장은 큰 문제는 아니지만 따라야 할 좋은 모델입니다.
Adam

1
최신 문서는 @HostListener를 사용하는 것이 좋습니다 : angular.io/docs/ts/latest/guide/...
saschwarz

11

2019 w Angular 8에 추가하기 위해

keypress 대신 keydown을 사용해야했습니다.

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

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

작업 Stacklitz


Angular 9 보고서 : keypress와 keydown 모두 일반 "asdf"키를 등록하지만 keydown 만 F4 및 기타 기능 키를 가져옵니다. 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...
    }
  }


0

이게 최선이라고 생각합니다

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

예를 들어 app.component에서

constructor(private eventManager: EventManager) {
    const removeGlobalEventListener = this.eventManager.addGlobalEventListener(
      'document',
      'keypress',
      (ev) => {
        console.log('ev', ev);
      }
    );
  }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.