Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you remove an event listener that uses "this" in TypeScript?

In JavaScript, for an event handler that needs access to private members and functions, I can rely on the function scope of those to be accessible within my event handler function, and do something like this:

theElement.addEventListener("click", onClick); 

and later:

theElement.removeEventListener("click", onClick); 

In TypeScript, I need to use an anonymous function to have this be the containing object, like so:

theElement.addEventListener("click", (event) => this.onClick(event)); 

In this case, I can't remove the anonymous function from the listening to the event. How do I have an event listener as part of a class (with access to private fields and methods), that I can remove later?

like image 913
Curyous Avatar asked Jun 25 '16 00:06

Curyous


People also ask

How do I remove an event listener?

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

How do I remove event listener from function?

element. removeEventListener("click", _listener, true); In this case, the event listener will be successfully removed because the removeEventListener 's argument matches the reference to the function object of the addEventListener .

How do you remove all event listeners from an element?

To remove all event listeners from an element: Use the cloneNode() method to clone the element. Replace the original element with the clone. The cloneNode() method copies the node's attributes and their values, but doesn't copy the event listeners.

Which of the following is used to remove the event listener?

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.


2 Answers

First, JavaScript and TypeScript behave the exact same way even if you write like that:

theElement.addEventListener("click", onClick); 

Second, this is how you can retain a reference to an anonymous function:

var f = (event) => this.onClick(event); theElement.addEventListener("click", f); // later theElement.removeEventListener("click", f); 

If you're dealing with event listeners, there's a useful pattern for your class methods to be bound:

class MyClass {     init(theElement) {         theElement.addEventListener("click", this.onClick);         theElement.addEventListener("click", this.onClick2);     }     print() {         console.log("print");     }     onClick() {         this.print() // possible error (`this` is not guaranteed to be MyClass)     }      onClick2 = () => {         this.print() // no error, `this` is guaranteed to be of type MyClass     } } 

Keep in mind, however, that this code will create a separate function onClick2 for every object of class MyClass. That can negatively affect your memory usage, if you create lots of MyClass instances and rarely use their onClick listeners.

like image 102
zlumer Avatar answered Oct 20 '22 00:10

zlumer


Already answered question, but IMO the answers here are not well designed regarding to OOP. So, here is my solution:

export class MyClass {    // create member that holds the function reference   protected clickEventListener: EventListener;          // inject the Element   constructor(protected theElement: Element) {        // wrap the class function `onClick` in an arrow function and assign      // to the class member `clickEventListener`        this.clickEventListener = () => this.onClick();    }    onClick() {     console.log("clicked");   }    init() {     // add the event listener to `theElement` and pass only the reference      // of `this.clickEventListener` (no round brackets '()')     this.theElement.addEventListener("click", this.clickEventListener);    }    destroy() {     // to remve the event listener also just pass the `clickEventListener` reference     this.theElement.removeEventListener("click", this.clickEventListener);    }  } 
like image 45
scipper Avatar answered Oct 19 '22 23:10

scipper