mousemove triggers change detection continuously in Angular

Viewed 1854

I've noticed mousemove on certain element triggers change detection continuously. I've researched this issue and discovered they suggest to use runOutsideAngular method of NgZone.

So I tried like,

this.zone.runOutsideAngular(() => {
  this.element.addEventListener('mousemove', {});
});

which didn't work at all.

Did I misuse runOutsideAngular or is there any other workaround to prevent the endless change detection on mousemove event? Any insight would be appreciated!

2 Answers

@EDIT For the comment question: the canvas element rendered by a third party library

Read this

For general purpose:

You need to use a renderer: Renderer2 listener.

Please read this Article

import { Component, OnInit, OnDestroy, NgZone, Renderer2, ViewChild, ElementRef } from '@angular/core';

@Component({
  selector: 'app-mouse-tracker',
  templateUrl: './mouse-tracker.component.html',
  styleUrls: ['./mouse-tracker.component.css']
})
export class MouseTrackerComponent implements OnInit, OnDestroy {
  @ViewChild('area', { static: true }) area: ElementRef<HTMLDivElement>;
  private unlisten: Function;

  constructor(private ngZone: NgZone, private renderer: Renderer2) { }

  ngOnInit() {
    this.ngZone.runOutsideAngular(() => {
      this.unlisten = this.renderer.listen(
        this.area.nativeElement,
        'mousemove',
        () => this.drawLine()
      );
    });
  }

  ngOnDestroy() {
    this.unlisten();
  }

  drawLine() {
    console.log('Drawing a line which does not require bindings update...');
  }

  getLabel(): string {
    console.log('Label is being computed...');

    return 'exemplary label';
  }
}

and template:

<p>mouse-tracker works!</p>
<p>{{ getLabel() }}</p>

<div #area></div>

I had this problem when the user was dragging dialog windows.

The solution was to inject ChangeDetectorRef and call detach() onMouseDown and reattach() onMouseUp

Related