Javascript event handler with parameters

JavascriptEventsEvent HandlingHandler

Javascript Problem Overview


I want to make an eventHandler that passes the event and some parameters. The problem is that the function doesn't get the element. Here is an example:

doClick = function(func){
	var elem = .. // the element where it is all about
	elem.onclick = function(e){
		func(e, elem);
	}
}
doClick(function(e, element){
	// do stuff with element and the event
});

The elem must be defined outside of anonymous function. How can i get the passed element to use within the anonymous function? Is there a way to do this?

And what about addEventListener? I don't seem to be able to pass the event through an addEventListener at all do I ?

Update

I seemed to fix the problem with 'this'

doClick = function(func){
	var that = this;
	this.element.onclick = function(e){
		func(e, that);
	}
}

Where this contains this.element that i can access in the function.

The addEventListener

But i'm wondering about the addEventListener:

function doClick(elem, func){
	element.addEventListener('click', func(event, elem), false);
}

Javascript Solutions


Solution 1 - Javascript

I don't understand exactly what your code is trying to do, but you can make variables available in any event handler using the advantages of function closures:

function addClickHandler(elem, arg1, arg2) {
    elem.addEventListener('click', function(e) {
        // in the event handler function here, you can directly refer
        // to arg1 and arg2 from the parent function arguments
    }, false);
}

Depending upon your exact coding situation, you can pretty much always make some sort of closure preserve access to the variables for you.

From your comments, if what you're trying to accomplish is this:

element.addEventListener('click', func(event, this.elements[i]))

Then, you could do this with a self executing function (IIFE) that captures the arguments you want in a closure as it executes and returns the actual event handler function:

element.addEventListener('click', (function(passedInElement) {
    return function(e) {func(e, passedInElement); };
}) (this.elements[i]), false);

For more info on how an IIFE works, see these other references:

https://stackoverflow.com/questions/19610586/javascript-wrapping-code-inside-anonymous-function/19610626#19610626

https://stackoverflow.com/questions/12332353/immediately-invoked-function-expression-iife-in-javascript-passing-jquery

https://stackoverflow.com/questions/23124067/what-are-good-use-cases-for-javascript-self-executing-anonymous-functions

This last version is perhaps easier to see what it's doing like this:

// return our event handler while capturing an argument in the closure
function handleEvent(passedInElement) {
    return function(e) {
        func(e, passedInElement); 
    };
}

element.addEventListener('click', handleEvent(this.elements[i]));

It is also possible to use .bind() to add arguments to a callback. Any arguments you pass to .bind() will be prepended to the arguments that the callback itself will have. So, you could do this:

elem.addEventListener('click', function(a1, a2, e) {
    // inside the event handler, you have access to both your arguments
    // and the event object that the event handler passes
}.bind(elem, arg1, arg2));

Solution 2 - Javascript

It is an old question but a common one. So let me add this one here.

With arrow function syntax you can achieve it more succinct way since it is lexically binded and can be chained.

An arrow function expression is a syntactically compact alternative to a regular function expression, although without its own bindings to the this, arguments, super, or new.target keywords.

const event_handler = (event, arg) => console.log(event, arg);
el.addEventListener('click', (event) => event_handler(event, 'An argument'));

If you need to clean up the event listener:

// Let's use use good old function sytax
function event_handler(event, arg) {
  console.log(event, arg);
}

// Assign the listener callback to a variable
var doClick = (event) => event_handler(event, 'An argument'); 

el.addEventListener('click', doClick);

// Do some work...

// Then later in the code, clean up
el.removeEventListener('click', doClick);

Here is crazy one-liner:

// You can replace console.log with some other callback function
el.addEventListener('click', (event) => ((arg) => console.log(event, arg))('An argument'));

More docile version: More appropriate for any sane work.

el.addEventListener('click', (event) => ((arg) => {
  console.log(event, arg);
})('An argument'));

Solution 3 - Javascript

Something you can try is using the bind method, I think this achieves what you were asking for. If nothing else, it's still very useful.

function doClick(elem, func) {
  var diffElem = document.getElementById('some_element'); //could be the same or different element than the element in the doClick argument
  diffElem.addEventListener('click', func.bind(diffElem, elem))
}

function clickEvent(elem, evt) {
  console.log(this);
  console.log(elem); 
  // 'this' and elem can be the same thing if the first parameter 
  // of the bind method is the element the event is being attached to from the argument passed to doClick
  console.log(evt);
}

var elem = document.getElementById('elem_to_do_stuff_with');
doClick(elem, clickEvent);

Solution 4 - Javascript

Given the update to the original question, it seems like there is trouble with the context ("this") while passing event handlers. The basics are explained e.g. here http://www.w3schools.com/js/js_function_invocation.asp

A simple working version of your example could read

var doClick = function(event, additionalParameter){
    // do stuff with event and this being the triggering event and caller
}

element.addEventListener('click', function(event)
{
  var additionalParameter = ...;
  doClick.call(this, event, additionalParameter );
}, false);

See also https://stackoverflow.com/questions/15455009/javascript-call-apply-vs-bind

Solution 5 - Javascript

Short answer:

x.addEventListener("click", function(e){myfunction(e, param1, param2)});

... 

function myfunction(e, param1, param1) {
    ... 
} 

Solution 6 - Javascript

Try,

const handleOnChange = (event, otherParameter) => {
    console.log(`${event.target.value}`);
    console.log(`${otherParameter}`);
}

<Select onchange= (event) => {
    handleOnChange(event, otherParameter);
}>

Solution 7 - Javascript

this inside of doThings is the window object. Try this instead:

var doThings = function (element) {
    var eventHandler = function(ev, func){
        if (element[ev] == undefined) {
            return;
        }

        element[ev] = function(e){
            func(e, element);
        }
    };

    return {
        eventHandler: eventHandler
    };
};

Solution 8 - Javascript

let obj = MyObject();

elem.someEvent( function(){ obj.func(param) } );

//calls the MyObject.func, passing the param.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionsebas2dayView Question on Stackoverflow
Solution 1 - Javascriptjfriend00View Answer on Stackoverflow
Solution 2 - JavascriptsnnsnnView Answer on Stackoverflow
Solution 3 - JavascriptKnight YoshiView Answer on Stackoverflow
Solution 4 - JavascriptEchsecutorView Answer on Stackoverflow
Solution 5 - Javascriptuser3093134View Answer on Stackoverflow
Solution 6 - JavascriptManil MallaView Answer on Stackoverflow
Solution 7 - JavascriptjbabeyView Answer on Stackoverflow
Solution 8 - JavascriptBaznrView Answer on Stackoverflow