Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 document.removeEventListener doesn't work in class

I can't remove event when action is end. I init event by click:

<span class="leftTopPoint" (click)="initResize($event)"></span>

export class SectionComponent {
    ...

    initResize(e): void {
        this.mouseX = e.clientX;
        this.mouseY = e.clientY;

        document.addEventListener('mousemove', this.onResize.bind(this), false);
        document.addEventListener('mouseup', this.stopResize.bind(this), false);
    }
}

I used .bind(this) and then pointer this is okay, but when I call to method of stopResize(), removeEventListener doesn't work. Method onResize() still work.

export class SectionComponent { ...
    stopResize(e): void {
        document.removeEventListener('mousemove', this.onResize, false);
        document.removeEventListener('mouseup', this.stopResize, false);
    }
}
like image 539
GGG205 Avatar asked Jun 24 '17 16:06

GGG205


People also ask

Why remove event listeners not working?

To resolve the removeEventListener not working issue, make sure to pass the same function to the addEventListener and removeEventListener methods. Passing a function that points to a different location in memory will not remove the listener.

How does removeEventListener work?

The removeEventListener() is an inbuilt function in JavaScript which removes an event handler from an element for a attached event. for example, if a button is disabled after one click you can use removeEventListener() to remove a click event listener.

Why is addEventListener not a function?

addeventListener is not a function", which means that the function we're calling is not recognized by the JavaScript interpreter. Often, this error message actually means that we've spelled something wrong. If you are not sure of the correct spelling of a piece of syntax, it is often good to look up the feature on MDN.

How to clear event listeners?

Event listeners can also be removed by passing an AbortSignal to an addEventListener() and then later calling abort() on the controller owning the signal.


2 Answers

Here is an elegant way with little boilerplate by using the fat arrow function:

export class AppComponent {
  private classMember = 'aClassMember';

  // use the fat arrow to bind the event
  private eventListener = () => {
    console.log(this.classMember);
  };

  registerEvent() {
    this.htmlEl.addEventListener('click', this.eventListener);
  );

  unregisterEvent() {
    this.htmlEl.removeEventListener('click', this.eventListener);
  );
}

hints:

  • use passive event handler, unless you want to call preventDefaults
  • when you want to avoid that the event triggers the Angular change detection use runOutsideAngular()
  • full stackblitz example
like image 56
TmTron Avatar answered Oct 18 '22 09:10

TmTron


You have to specify the same function to removeEventListener as you provided to addEventListener. The function returned by bind is not the same as the original function (if it were, it would have the this issue).

So you'll have to store your bound functions and use them when calling removeEventListener.

initResize(e): void {
    this.mouseX = e.clientX;
    this.mouseY = e.clientY;

    if (!this.onResizeBound) {
        this.onResizeBound = this.onResize.bind(this);
    }
    if (!this.stopResizeBound) {
        this.stopResizeBound = this.stopResize.bind(this);
    }

    document.addEventListener('mousemove', this.onResizeBound, false);
    document.addEventListener('mouseup', this.stopResizeBound, false);
}

and

stopResize(e): void {
    document.removeEventListener('mousemove', this.onResizeBound, false);
    document.removeEventListener('mouseup', this.stopResizeBound, false);
}
like image 36
T.J. Crowder Avatar answered Oct 18 '22 09:10

T.J. Crowder