House3272 House3272 - 2 months ago 9
Javascript Question

Javascript, addEventListener callback function executes immediately and only once?

I've noticed a difference between

function
and
function()
for addEventListener's callback.
Which isn't a problem till I tried passing a parameter. Basically,

element.addEventListener("hover", logInput, false );
function logInput(){
console.log('registered!');
}


works as intended, but adding parenthesis will cause it log immediately, without continual response to the event trigger:

element.addEventListener("hover", logInput(), false );
function logInput(){
console.log('registered!');
}


Why is this? And how can I get it to work while passing a parameter such as:

element.addEventListener("hover", logOnInput(this), false );
function logOnInput(triggeredElement){
console.log(triggeredElement);
}

Answer

(If you really want the triggered element, don't pass anything. this will automatically be set to the triggered element.)

element.addEventListener("hover", logOnInput, false);
function logOnInput(){
    console.log(this);
}

To answer your more general question...

There are a few ways to pass a function as an argument with certain arguments already set (this is referred to as "partial application"). If you are able to use modern JavaScript features, the simplest way is probably to use an arrow function.

element.addEventListener("hover", () => logOnInput(foo), false);
function logOnInput(message){
    console.log(message);
}

This will only work on very modern browsers. It won't work, for example, in IE 11. In order to support older browsers, you can use the longer form of a function expression.

element.addEventListener("hover", function() {logOnInput(foo);}, false);
function logOnInput(message){
    console.log(message);
}

Or you could define a separate function (won't work with this but will work with other variables).

element.addEventListener("hover", logFooOnInput, false);
function logOnInput(triggeredElement){
    console.log(triggeredElement);
}
function logFooOnInput() {
    logOnInput(foo);
}

Or you could use bind.

element.addEventListener("hover", logOnInput.bind(null, foo), false);
function logOnInput(message){
    console.log(message);
}