Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add AND remove eventlistener with arguments and access element and event? - Javascript

Lets say I want to pass arguments to my function. I hear that I should do it by calling another function from within a function like this:

myElement.addEventListener("click",function whatever(event){
    myFunk(event,"some argument");
},false);

But what now if I want to remove it?

myElement.removeEventListener("click",whatever,false);

var myElement = document.querySelector('div')
function myFunk(e,m){
  console.log(e,m)
}
myElement.addEventListener("click",function whatever(event){
    myFunk(event,"some argument")
},false)

myElement.removeEventListener("click", whatever, false)
<div></div>

This returns a "whatever is not defined" error in the console. So does my function not have a name? Is "whatever" not its name? How now do I remove it?

I need a way to assign an event listener and pass it arguments, and then get rid of it later. How do I do this?

EDIT:

Okay, yes, I cannot refer to whatever because it is written inline. But the reason I am forced to use a function expression inline is because I want to pass it arguments. I want to pass it arguments because I don't want to have to define a new function for every time I want to change the behaviour. If I define an event listener using text on the "on" property I can easily swap out parameters:

element.onClick("myFunc('do one thing')");

element.onClick("myFunc('do a different thing')");

How do I do this with addEventListener, inline, removable, and with dynamic parameters?

like image 918
ADJenks Avatar asked Jul 14 '15 11:07

ADJenks


2 Answers

For addEventListener()'s second argument, do this:

whatever= function(event) {
  ...
}

… instead of this:

function whatever(event) {
  ...
}

You'll then be able to remove the event like this:

myElement.removeEventListener('click' , whatever);

To pass parameters to another event, use bind, like this:

whatever= myfunk.bind(myElement, parameter1, parameter2, ...)

Example

var myElement= document.getElementById('myElement');

function myfunk(s) {
  this.innerHTML+= '<br>'+s;
  myElement.removeEventListener('click', whatever);

  myElement.addEventListener(
    'click',
    whatever= myfunk.bind(myElement, 'Clicked again.')
  );
}

myElement.addEventListener(
  'click',
  whatever= myfunk.bind(myElement, 'Clicked once.')
);
<div id="myElement">Click me!</div>
like image 88
Rick Hitchcock Avatar answered Sep 23 '22 00:09

Rick Hitchcock


Maybe this will help you with your goal... generateHandler generates an event handler function for an input function, with an input argument and passes the "real handler" the event, the argument AND the handler instance for easy removal. It also returns that instance for removing the handler from outside.

I then show various ways of how this can be used. Hope this helps...

function generateHandler(f, arg) {
  var handler = function (evt) {
    f(evt, arg, handler);
  };
  return handler;
}

function realFunc(evt, arg, handler) {
  alert(arg);
  if(arg == 2) {
    document.getElementById('el').removeEventListener('click', handler);
    document.getElementById('el').innerHTML = 'I also do nothing now';
  }
}

function replace1Time(evt, arg, handler) {
  document.getElementById('el').removeEventListener('click', elHandler);
  elHandler = generateHandler(realFunc, 2);
  document.getElementById('el').addEventListener('click', elHandler);
  document.getElementById('el2').removeEventListener('click', handler);
  document.getElementById('el2').innerHTML = 'I do nothing now';
}

var elHandler = generateHandler(realFunc, 1);

document.getElementById('el').addEventListener('click', elHandler);
document.getElementById('el2').addEventListener('click', generateHandler(replace1Time));
<div id="el">Click me!</div>
<div id="el2">Click me to replace 1 time</div>
like image 22
Amit Avatar answered Sep 26 '22 00:09

Amit