Jessica Jessica - 3 months ago 10
Javascript Question

Add additional parameters to event function

I have an event, and I want to add additional parameters to the named function. I tried following 2 things:

myDiv.addEventListener('click', evt.call(this, event, 'hello'));


And

myDiv.addEventListener('click', evt(event, 'hello'));


And the problem with both of them, is they get called right away, and don't get called when you click
myDiv
, i.e. when it's supposed to get called.

How can I add additional parameters to the named function event?

JSFiddle





console.clear();

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

function evt(event, param1) {
console.log(event + ' and ' + param1)
}

myDiv.addEventListener('click', evt.call(this, event, 'hello'));

#myDiv {
width: 200px;
height: 200px;
background-color: green;
}

<div id="myDiv"></div>




Answer

You can use an anonymous wrapper:

myDiv.addEventListener('click', function(event) {
    return evt.call(this, event, 'hello');
});

Alternately, you can give yourself a utility function (I tend to call it curry; purist may argue with that name). Here's an unoptimized off-the-cuff:

Object.defineProperty(Function.prototype, "curry", {
    value: function() {
        var f = this;
        var boundArgs = Array.prototype.slice.call(arguments);
        return function() {
            return f.apply(this, boundArgs.concat(Array.prototype.slice.call(arguments)));
        };
    }
});

Then:

myDiv.addEventListener('click', evt.curry('hello'));

But you have to change the order of arguments in evt for that:

function evt(param1, event) {
  console.log(event + ' and ' + param1)
}

...since my version of curry passes it the curried arguments first, then the arguments that the curried version was called with. Although I suppose it's easy enough to swap them around if you prefer.

Here's that curry function in ES2015+:

Object.defineProperty(Function.prototype, "curry", {
    value(...boundArgs) {
        var f = this;
        return function(...callArgs) {
            return f.call(this, ...boundArgs, ...callArgs);
        };
    }
});