2

I have no idea of how to do this, I want to pass an argument to the callback function "ctrlDeleteItem":

document.querySelector('.container').addEventListener('click', ctrlDeleteItem);

But if I do that, I lose access to the event property, example:

document.querySelector('.container').addEventListener('click', ctrlDeleteItem(item));

function ctrlDeleteItem(item, event) {
  return function() {
    console.log(item);
    console.log(event);
  }
}

How can I still pass the event as a parameter? I can't find how to do it, thanks.

BraisC
  • 199
  • 2
  • 10
  • 1
    Checkout this answer https://stackoverflow.com/a/11986895/598478 – Chibuzo Aug 06 '18 at 00:25
  • There is some event delegation, so event.target is not the same element that I am selecting with document.querySelector('.container') – BraisC Aug 06 '18 at 00:35

2 Answers2

3

The accepted answer is incorrect because it will cause the ctrlDeleteItem function to be executed immediately. That can be shown by adding a console.log("test") statement to the ctrlDeleteItem() function - you'll get the message immediately.

The correct solution is to set up a "wrapper" callback function that will receive the event as usual and then have that wrapper call the actual callback function with whatever arguments are needed. The wrapper can pass the event to the actual callback if desired.

const item = 'foo';
document.querySelector('.container').addEventListener('click', function(evt){ 
  ctrlDeleteItem(evt, item);
});

function ctrlDeleteItem(evt, item) {
    console.log(evt.type, item);
    console.log(event.target.className);
}
<div class="container">container</div>
Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
0

Put event as an argument to the returned function in ctrlDeleteItem, so that it will be used properly as the event in the listener:

function ctrlDeleteItem(item) {
  return function(event) {
    console.log(item);
    console.log(event);
  }
}

const item = 'foo';
document.querySelector('.container').addEventListener('click', ctrlDeleteItem(item));

function ctrlDeleteItem(item) {
  return function(event) {
    console.log(item);
    console.log(event.target.className);
  }
}
<div class="container">container</div>
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • This is not correct. See my answer below for why and the correct solution. – Scott Marcus Aug 06 '18 at 00:58
  • 1
    But from his code, it looked like he *did* want to invoke `ctrlDeleteItem` immediately. If you essentially want to pass an additional argument to the listener at the time you add the listener, using a function that returns a function *is* a fine way to accomplish that – CertainPerformance Aug 06 '18 at 01:00
  • 1
    I interpret it as him trying any code that would work. He doesn't state that running `ctrlDeleteItem` immediately is a requirement. He only states that he wants to pass arguments to the callback without losing the event reference. Unless we need dynamic callback construction, this solution becomes an anti-pattern. – Scott Marcus Aug 06 '18 at 01:06
  • Yeah well, I used a closure there just so both logs executed when the event triggers, and not automatically, I didnt know that there was another way to avoid the invocation of the listener function... thanks to both of you, both answers helped me to learn how this works. – BraisC Aug 06 '18 at 01:14