ฉันจะฟังเหตุการณ์การกดแป้นทั้งหน้าได้อย่างไร?


110

ฉันกำลังมองหาวิธีผูกฟังก์ชันเข้ากับทั้งหน้าของฉัน (เมื่อผู้ใช้กดปุ่มฉันต้องการให้เรียกใช้ฟังก์ชันใน component.ts ของฉัน)

มันง่ายมากใน AngularJS ด้วย a ng-keypressแต่ใช้ไม่ได้กับ(keypress)="handleInput($event)".

ฉันลองใช้กระดาษห่อ div ทั้งหน้า แต่ดูเหมือนจะไม่ได้ผล จะใช้งานได้เมื่อโฟกัสอยู่ที่มันเท่านั้น

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

คุณลองแล้วwindow:keypressหรือยัง?
KarolDepka

คำตอบ:


206

ฉันจะใช้มัณฑนากร@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 ฟัง

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
ดีขึ้น ต้องเพิ่มการนำเข้า {HostListener} จาก "@ angular / core" และโทรได้ทุกที่ในส่วนประกอบ แม้แต่ตัวควบคุมด้านข้างก็ยังทำงานได้ดี
gnganapath

23
ขอบคุณสำหรับสิ่งนี้ แต่เป็นเพียงการแจ้งเตือนสำหรับผู้อ่านในอนาคต: หากคุณต้องการปุ่มลูกศรให้ใช้คีย์ดาวน์แทนการกดแป้น
Troels Larsen

14
หากคุณต้องการescคีย์ให้ใช้keyupเหตุการณ์ ขอบคุณ @TroelsLarsen
Aron Lorincz

@yurzui ฉันจะใช้เหตุการณ์นี้สำหรับส่วนประกอบเฉพาะได้อย่างไรไม่ทั้งหน้า
kamalav

1
@yurzui ฉันจะตรวจจับfunction-key(F1, F2, F3, ... ) ได้อย่างไร?
Arpit Kumar

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ünterZöchbauer

อย่างที่ฉันพูดอาจเป็นความผิดพลาดในส่วนของฉัน แต่นั่นคือสิ่งที่ต้องทำเพื่อให้ได้ผลสำหรับฉัน :)
อดัม

ประโยชน์ของสิ่งนี้กับการใช้ document.addEventListener คืออะไร? เป็นเพียงประเด็นของการแยก DOM ออกไปหรือไม่?
Ixonal

@Ixonal # 2 ในบทความนี้อธิบายได้ดีกว่าที่ฉันทำได้: angularjs.blogspot.ca/2016/04/…โดยพื้นฐานแล้วไม่ใช่วิธี "เชิงมุม" เพราะใช้คู่กับเบราว์เซอร์และไม่สามารถทดสอบได้ อาจจะไม่ใช่เรื่องใหญ่ในตอนนี้ แต่ก็เป็นแบบอย่างที่ดีในการปฏิบัติตาม
อดัม

1
เอกสารล่าสุดแนะนำให้ใช้ @HostListener: angular.io/docs/ts/latest/guide/…
saschwarz

12

เพียงเพิ่มสิ่งนี้ในปี 2019 w Angular 8

แทนที่จะกดแป้นฉันต้องใช้คีย์ดาวน์

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

ถึง

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

Stacklitzทำงาน


รายงาน Angular 9: ทั้งการกดแป้นและการกดแป้นลงจะลงทะเบียนคีย์ "asdf" ตามปกติ แต่การกดแป้นลงเท่านั้นที่จะได้รับ F4 และแป้นฟังก์ชันอื่น ๆ การกดแป้นพิมพ์อาจได้รับคีย์คอมโบเช่น CTRL-Z คีย์ดาวน์จะแปลความหมายแยกกัน (คีย์ CTRL จากนั้นมิลลิวินาทีต่อมาเป็นคีย์ Z)
Anders8

4

หากคุณต้องการทำเหตุการณ์ใด ๆ บนการกดปุ่มแป้นพิมพ์ใด ๆ ในกรณีนั้นคุณสามารถใช้ @HostListener สำหรับสิ่งนี้คุณต้องนำเข้า HostListener ในไฟล์ ts คอมโพเนนต์ของคุณ

นำเข้า {HostListener} จาก "@ angular / core";
จากนั้นใช้ฟังก์ชันด้านล่างที่ใดก็ได้ในไฟล์ ts คอมโพเนนต์ของคุณ

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


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.