Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bind with addEventListener

When using bind() on an Event Listener in JavaScript I can no longer get the element with "this".

Here is my code:

function callback(){

     console.log(this.someVar);
     // Works fine

     console.log(this);
     // No longer refers to the element, outputs "Object"

}

callback = callback.bind({someVar: 1234});

element.addEventListener('click', callback);

Any idea on how to fix this?

like image 540
Ood Avatar asked Mar 17 '26 10:03

Ood


1 Answers

If you want to pass one variable but keep the this context, then you can use currying or partial application:

Curry

Your function has to receive a value and return another function. This way you can do the following:

function callback(num) {
  return function() {
    console.log(num);
    console.log(this.id);
  }
}

var number = 1;

document.getElementById("hello").addEventListener("click", callback(number));

//change the variable
number = 2;
document.getElementById("world").addEventListener("click", callback(number));

//change the variable again
number = 3;
<button id="hello">Hello</button>
<button id="world">World</button>

Partial application

Same idea but instead of having your callback return a new function, it will just take a single argument and work normally, you need another function that will do the partial application:

function callback(num) {
  console.log(num);
  console.log(this.id);
}

var number = 1;

document.getElementById("hello").addEventListener("click", partial(callback, number));

//change the variable
number = 2;
document.getElementById("world").addEventListener("click", partial(callback, number));

//change the variable again
number = 3;


function partial(fn, arg) {
  return function() {
    return fn.call(this, arg);
  }
}
<button id="hello">Hello</button>
<button id="world">World</button>

The partial application function can be generalised to handle any amount or arguments

In ES6:

function partial(fn, ...args) {
  return function(...otherArgs) {
    return fn.apply(this, [...args, ...otherArgs]);
  }
}

In ES5:

function partial(fn) {
  var args = [].prototype.slice.call(arguments, 1);
  return function() {
    var otherArgs = [].[].prototype.slice.call(arguments);
    return fn.apply(this, args.concat(otherArgs));
  }
}
like image 121
VLAZ Avatar answered Mar 19 '26 00:03

VLAZ



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!