[javascript] How to pass parameter to function using in addEventListener?

In the traditional way to add event listener:

function getComboA(sel) {
    var value = sel.options[sel.selectedIndex].value;  
}

<select id="comboA" onchange="getComboA(this)">
<option value="">Select combo</option>
<option value="Value1">Text1</option>
<option value="Value2">Text2</option>
<option value="Value3">Text3</option>
</select>

But I wanted to adapt to the addEventListener way:

productLineSelect.addEventListener('change',getSelection(this),false);

function getSelection(sel){
    var value = sel.options[sel.selectedIndex].value;
    alert(value);
}

It doesn't work because I can't pass any parameter in getSelection() as the second parameter in addEventListener method? As far as I know I can only use the function name without parenthesises.

Any idea?

BTW, please look at my previous question about console.log doesn't work in safari 6.0 developer inspector, I can't write any output in the console, which is frustrating.

This question is related to javascript html javascript-events

The answer is


In the first line of your JS code:

select.addEventListener('change', getSelection(this), false);

you're invoking getSelection by placing (this) behind the function reference. That is most likely not what you want, because you're now passing the return value of that call to addEventListener, instead of a reference to the actual function itself.


In a function invoked by addEventListener the value for this will automatically be set to the object the listener is attached to, productLineSelect in this case.

If that is what you want, you can just pass the function reference and this will in this example be select in invocations from addEventListener:

select.addEventListener('change', getSelection, false);

If that is not what you want, you'd best bind your value for this to the function you're passing to addEventListener:

var thisArg = { custom: 'object' };
select.addEventListener('change', getSelection.bind(thisArg), false);

The .bind part is also a call, but this call just returns the same function we're calling bind on, with the value for this inside that function scope fixed to thisArg, effectively overriding the dynamic nature of this-binding.


To get to your actual question: "How to pass parameters to function in addEventListener?"

You would have to use an additional function definition:

var globalVar = 'global';

productLineSelect.addEventListener('change', function(event) {
    var localVar = 'local';
    getSelection(event, this, globalVar, localVar);
}, false);

Now we pass the event object, a reference to the value of this inside the callback of addEventListener, a variable defined and initialised inside that callback, and a variable from outside the entire addEventListener call to your own getSelection function.


We also might again have an object of our choice to be this inside the outer callback:

var thisArg = { custom: 'object' };
var globalVar = 'global';

productLineSelect.addEventListener('change', function(event) {
    var localVar = 'local';
    getSelection(event, this, globalVar, localVar);
}.bind(thisArg), false);

When you use addEventListener, this will be bound automatically. So if you want a reference to the element on which the event handler is installed, just use this from within your function:

productLineSelect.addEventListener('change',getSelection,false);

function getSelection(){
    var value = sel.options[this.selectedIndex].value;
    alert(value);
}

If you want to pass in some other argument from the context where you call addEventListener, you can use a closure, like this:

productLineSelect.addEventListener('change', function(){ 
    // pass in `this` (the element), and someOtherVar
    getSelection(this, someOtherVar); 
},false);

function getSelection(sel, someOtherVar){
    var value = sel.options[sel.selectedIndex].value;
    alert(value);
    alert(someOtherVar);
}

If the this value you want is the just the object that you bound the event handler to, then addEventListener() already does that for you. When you do this:

productLineSelect.addEventListener('change', getSelection, false);

the getSelection function will already be called with this set to the object that the event handler was bound to. It will also be passed an argument that represents the event object which has all sorts of object information about the event.

function getSelection(event) {
    // this will be set to the object that the event handler was bound to
    // event is all the detailed information about the event
}

If the desired this value is some other value than the object you bound the event handler to, you can just do this:

var self = this;
productLineSelect.addEventListener('change',function() {
    getSelection(self)
},false);

By way of explanation:

  1. You save away the value of this into a local variable in your other event handler.
  2. You then create an anonymous function to pass addEventListener.
  3. In that anonymous function, you call your actual function and pass it the saved value of this.

Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to html

Embed ruby within URL : Middleman Blog Please help me convert this script to a simple image slider Generating a list of pages (not posts) without the index file Why there is this "clear" class before footer? Is it possible to change the content HTML5 alert messages? Getting all files in directory with ajax DevTools failed to load SourceMap: Could not load content for chrome-extension How to set width of mat-table column in angular? How to open a link in new tab using angular? ERROR Error: Uncaught (in promise), Cannot match any routes. URL Segment

Examples related to javascript-events

How to fire an event on class change using jQuery? how to toggle (hide/show) a table onClick of <a> tag in java script How to pass parameter to function using in addEventListener? Open popup and refresh parent page on close popup How to remove all listeners in an element? Destroy or remove a view in Backbone.js Add event handler for body.onload by javascript within <body> part How to trigger jQuery change event in code How can I trigger an onchange event manually? Intercept page exit event