我正在将拖动功能实现到一个角度应用程序:
http://jsfiddle.net/Jjgmz/1/
部分原因是在文档对象上侦听mousemove事件.
$(document).mousemove(function(e) {});
如何在组件内部监听文档对象?
<div id="Box"></div>
我正在使用Angular 4.
1)使用@HostListener(
docs).这是首选的方法,大多数时候应该足够了.
import {Component,NgModule,HostListener} from '@angular/core' @Component({ ... }) export class MyComponent { @HostListener('document:mousemove',['$event']) onMouseMove(e) { console.log(e); } .. }
2)与上面类似,你也可以在任何DOM元素上使用(document:event)=“handler”,但是上面的解决方案是首选的,因为代码更清晰.通过使用它,从类中可以直接看出,您有一个全局事件侦听器,并且您可能会不必要地添加其他事件.
@Component({ selector: 'my-app',template: ` <div (document:mousemove)="onMouseMove($event)" id="Box"></div> `,}) export class MyComponent { onMouseMove(e) { console.log(e); } }
3)渲染器(docs)是较低级别的解决方案;当您不希望使用方法使代码混乱时很有用,但是在其他地方处理它们,例如在钩子中,如下面的代码片段所示.但是要小心,因为您仍然需要删除事件侦听器以防止内存泄漏;当你知道你不再需要它时,或者在OnDestroy钩子中,要么这样做.
import { Component,Renderer2 } from '@angular/core'; @Component({ ... }) export class MyComponent { globalListenFunc: Function; constructor(private renderer: Renderer2) {} ngOnInit() { this.globalListenFunc = this.renderer.listen('document','mousemove',e => { console.log(e); }); } ngOnDestroy() { // remove listener this.globalListenFunc(); } }
4)第一个例子的替代方案是一个主机属性,它不受Angular Style Guide的支持,因为你现在可以在两个地方跟踪功能名称,这两个地方的代码可能相差很远.尽可能优先考虑第一个版本.
@Component({ ... host: { '(document:mousemove)': 'onMouseMove($event)' } }) export class MyComponent { onMouseMove(e) { console.log(e); } }
5)Angular所采用的反应方式是使用Observable.fromEvent.这为您提供了在执行函数之前转换流的所有RxJS operators的好处.但要小心,因为您需要手动取消订阅以避免内存泄漏(除非您使用异步管道直接在模板中订阅;这将为您处理取消订阅).另外,不要忘记添加 – 导入运算符,如下面的代码段所示.
import { Subscription,fromEvent } from 'rxjs'; @Component({ ... }) export class MyComponent { subscription: Subscription; ngOnInit() { this.subscription = fromEvent(document,'mousemove') .subscribe(e => { console.log(e); }); } ngOnDestroy() { this.subscription.unsubscribe(); } }
6)当然,document.addEventListener也是一个解决方案;但这不是Angular应用程序中的预期用途;你应该选择不同的方式.不鼓励直接访问DOM,因为它破坏了Angular对DOM操作的整洁封装.你也可能遇到Universal和SSR的问题.