代码之家  ›  专栏  ›  技术社区  ›  sanjihan

如何在Angular中侦听Document对象上的mousemove事件

  •  32
  • sanjihan  · 技术社区  · 8 年前

    我正在将拖动功能实现到angular应用程序中: http://jsfiddle.net/Jjgmz/1/

    其中一部分就是倾听 mousemove

    $(document).mousemove(function(e) {});
    

    如何侦听组件内部的文档对象?

    假设这是组件的内容。html文件:

    <div id="box"></div>
    

    我使用角度4。

    1 回复  |  直到 8 年前
        1
  •  122
  •   yurzui    7 年前

    1) 使用 @HostListener ( docs ). 这是首选的方法,在大多数情况下应该足够了。

    import {Component, NgModule, HostListener} from '@angular/core'
    
    @Component({
      ...
    })
    export class MyComponent {
      @HostListener('document:mousemove', ['$event']) 
      onMouseMove(e) {
        console.log(e);
      }
      ..
    }
    

    2) 与上述类似,您也可以使用 (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) The 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) 第一个示例的替代方案是 ,这被角度样式指南所阻止,因为现在您可以在代码中物理上相距很远的两个位置跟踪函数名。尽可能选择第一个版本。

    @Component({
      ...
      host: {
        '(document:mousemove)': 'onMouseMove($event)'
      }
    })
    export class MyComponent {
      onMouseMove(e) {
        console.log(e);
      }
    }
    

    Observable.fromEvent . 这让你受益匪浅 RxJS operators 用于在执行函数之前转换流。但是要小心,因为您需要手动取消订阅以避免内存泄漏(除非您使用 async 管这将为您处理退订)。另外,不要忘记添加import操作符,如以下代码段所示。

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

    document.addEventListener 也是一个解决方案;但这不是Angular应用程序的预期用途;你应该选择不同的方式。不鼓励直接访问DOM,因为它破坏了Angular对DOM操作的简洁封装。此外,您可能会在Universal和SSR方面遇到问题。

    推荐文章