我如何在整个页面上收听按键事件?

时间:2016-05-21 11:45:15

标签: typescript angular keypress key-bindings

我正在寻找一种方法将函数绑定到我的整个页面(当用户按下某个键时,我希望它在我的conponent.ts中触发一个函数)

使用@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main_screen); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); Fragment fragment = new Mapfragment(); DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); ActionBarDrawerToggle toggle = new ActionBarDrawerToggle( this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); drawer.setDrawerListener(toggle); toggle.syncState(); NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view); navigationView.setNavigationItemSelectedListener(this); View hView = navigationView.getHeaderView(0); TextView username_header = (TextView)hView.findViewById(R.id.username_header); username_header.setText(UserDetails.getInstance().getUsername()); ImageView img= (ImageView)hView.findViewById(R.id.imageView); img.setImageBitmap(UserDetails.getInstance().getImage()); //adding main fragment upon Main screen activity Oncreate android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager(); fragmentManager.beginTransaction().add(R.id.frame_layout_placeholder,fragment).commit(); } @Override public void onBackPressed() { DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); if (drawer.isDrawerOpen(GravityCompat.START)) { drawer.closeDrawer(GravityCompat.START); } else { super.onBackPressed(); } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main_screen, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } @SuppressWarnings("StatementWithEmptyBody") @Override public boolean onNavigationItemSelected(MenuItem item) { // Handle navigation view item clicks here. android.support.v4.app.Fragment fragment = null; android.support.v4.app.FragmentTransaction fragmentManager = getSupportFragmentManager().beginTransaction(); int id = item.getItemId(); if (id == R.id.map_frag_item) { fragment = new Mapfragment(); } else if (id == R.id.nav_gallery) { fragment = new FragmentTwo(); } else if (id == R.id.nav_slideshow) { } else if (id == R.id.nav_manage) { } else if (id == R.id.nav_share) { } else if (id == R.id.nav_send) { } fragmentManager.replace(R.id.frame_layout_placeholder, fragment).commit(); DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); drawer.closeDrawer(GravityCompat.START); return true; } 在Angular 1中很容易,但它不适用于ng-keypress

我在整个页面上使用div包装器尝试了它但它似乎不起作用。 它仅在焦点集中时才有效。

(keypress)="handleInput($event)"

谢谢!

6 个答案:

答案 0 :(得分:143)

我会在你的组件中使用@HostListener装饰器:

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

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

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

还有其他选项,如:

@Component装饰器

中的

主机属性

Angular建议在主机属性https://angular.io/guide/styleguide#style-06-03

上使用@HostListener装饰器
@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();
  }
}

答案 1 :(得分:16)

yurzui的回答对我不起作用,可能是一个不同的RC版本,或者我可能是个错误。无论哪种方式,这里是我如何使用Angular2 RC4中的组件(现在已经过时了)。

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

答案 2 :(得分:2)

如果要在任何特定的键盘按钮上执行任何事件,在这种情况下,您可以使用@HostListener。为此,您必须在组件ts文件中导入HostListener。

导入{HostListener}来自&#39; @ angular / core&#39;;
然后在组件ts文件中的任何位置使用以下函数。

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

答案 3 :(得分:1)

我认为这做得最好

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

答案 4 :(得分:0)

只需在2019年Angular 8中添加到此,

我不得不使用keydown来代替按键

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

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

答案 5 :(得分:0)

请注意,不建议使用“ document:keypress”。我们应该改用document:keydown。

链接:https://developer.mozilla.org/fr/docs/Web/API/Document/keypress_event