Friday, 7 April 2023

RemoveEventListener added with bind - Easy

In html5 canvases, when you add an event listener to something, it persists even if the movie clip is no longer on the stage. This causes two problems:

1) This takes up memory because the memory will hold on to the movie clip as long as it still has event listeners. Not just for movie clips on previous frames, but also if you are dynamically adding and removing clips - they will never go away, and your animation will gradually (or quickly) grind to a halt.

2) You an accidentally add multiple listeners to movie clips, e.g. when adding a mouseup event after a mousedown event, which you might do for dragging a movie clip. This could lead to contradictory or exaggerated responses, as well as taking up memory.

You can check if movieclips have event listeners before adding them with 'hasEventListener' (pass the event), and remove event listeners with 'removeEventListener' (pass the event, and the function).

This won't work if you have used the bind function to control the scope of the function. You have to pass the bound version that was originally given. If you are adding the function to multiple movieClips, creating a variable for each bound function could get messy. One way around this is to get each movieClip to store it's own bound functions.

See the example below:

------------------------------

1    this.tempFunction = function(e) {
2        console.log('click');
3        this.removeEventListener('click',this.ck);
4    }
5
6    this.btn.addEventListener('click',this.btn.ck = this.tempFunction.bind(this.btn));

------------------------------

You should find that the first time you click the button, a message 'click' comes up in the console (Ctrl+Shift+i in Chrome), and then it stops responding.

6: This line adds an event listener to the button (this.btn), that will respond to a click. The function called in response to the click is this.tempFunction, and bind is used so that the tempFunction works from the perspective (or scope) of the button. 

This part: "this.btn.ck = this.tempFunction.bind(this.btn)" simultaneously passes a function that should respond to the event and assigns it to a variable at the same time, and this variable (this.btn.ck) belongs to the button (this.btn).

1: This line declares the function that will respond to the click event of btn.

3: Remember that when this function is called, it will run from the scope of the btn, so when the event is removed, we can pass it 'this.ck', because from the btn scope, that is how to refer to the function that was referred to in line 6.

WARNING: removeEventListener won't tell you if it doesn't work, i.e., if it can't find the event you are trying to remove, so check the event has really been removed.

No comments:

Post a Comment

Please enter your message here...