我正在将拖动功能实施到角度应用中:http://jsfiddle.net/Jjgmz/1/
部分原因是在文档对象上监听mousemove
事件。
$(document).mousemove(function(e) {});
如何在组件内部监听文档对象?
让我们假装这是component.html文件的内容:
<div id="box"></div>
我正在使用Angular 4。
答案 0 :(得分:59)
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)Renderer
(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的好处。但要小心,因为您需要手动取消订阅以避免内存泄漏(除非您使用async
管道直接在模板中订阅;这将为您处理取消订阅)。另外,不要忘记添加 - 导入运算符,如下面的代码段所示。
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的问题。