0

I have used a 'For loop' for creating several 'event handler functions'.These functions have the same name.For example: Code:

for(let x in array){
  element[x].addEventListener('click',eventhandler)
  function eventhandler(){
     bla bla....
     for(let x in array){
       element[x].removeEventListener('click',eventhandler)/*this line doesn't work*/
     }
  }
}

How do I remove all of these event listeners now? element[x].removeEventListener('click',eventhandler) doesn't work :(

  • Pass the event object to the handler, and do `event.currentTarget.removeEventListener('click', eventhandler);`. Notice also, that you must pull the function out of the loop, or pass the definition to `addEventListener`. – Teemu Jun 05 '21 at 11:14
  • but for every 'x' in the array I have to make a new function.So the function needs to be in the for loop. – Js_bliss Jun 05 '21 at 11:19
  • You shouldn't be using `for...in` on an array, it offers not guarantees of order and iterates all enumerable properties, use `for...of` instead. – pilchard Jun 05 '21 at 11:26
  • No, you must not declare new functions in the loop, pass the function instead. The idea of the ability of passing a reference to `addEventListener` makes it possible to use the same function for multiple events, it saves some memory. When you're defining `array` and `eventhandler` in the same scope, `array` is accessible in the function, you don't need a loop for that. Notice also what pilchard said. – Teemu Jun 05 '21 at 11:30
  • I want to remove 'ALL' of the eventlisteners in the '2nd for loop'.So the order is insignificant. – Js_bliss Jun 05 '21 at 11:30
  • Yes, but the fact, that an array might contain some enumerable properties additionally to the indexed propertie, the loop will break because the additional property doesn't have `removeEventListner` method. – Teemu Jun 05 '21 at 11:32
  • Take a look at [this example](https://jsfiddle.net/9nrq80ay/), you might get some ideas. Actually, declaring a function in a loop doesn't create a new function on every round, the function created on the first round is just rewritten. But it's still a lot of unnecessary work, and is considered as a bad practice. Often you can benefit from [event delegation](https://stackoverflow.com/questions/1687296/what-is-dom-event-delegation) too, when delegating events you might need only a single listener, you won't need any loops at all. – Teemu Jun 05 '21 at 11:45
  • 'function eventHandler (e) '--- here, you have given a parameter to the function?What is this parameter for? and when you call this function you don't pass it any argument?so what is this parameter for? – Js_bliss Jun 05 '21 at 11:57
  • You don't call that function, it's called from the event queue by the browser with that argument. The parameter is the event object, which contains a lot of information of the event, ex. the element which triggered the event (`e.target`), mouseevent objects contain the coordinates of the mouse, keyevents contain the name and code of the pressed key etc. – Teemu Jun 05 '21 at 12:03
  • https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events#event_objects – Teemu Jun 05 '21 at 12:17
  • 1
    Thank you teemu for that example! I have learned about the ‘event object’ because of that. – Js_bliss Jun 05 '21 at 14:11

1 Answers1

0

You could separate your event listeners logic from the cleanup logic, and attach the cleanup separately like this:

const cleanup = array.map((x, i) => {
  function eventhandler(){
     // bla bla....
  }

  element[i].addEventListener('click', eventhandler);
  
  return () => element[i].removeEventListener(eventhandler)
})

array.forEach((x, i) => {
  element[i].addEventListener('click', () => cleanup.forEach(y => y()));
})
Guerric P
  • 30,447
  • 6
  • 48
  • 86