475

The situation is somewhat like-

var someVar = some_other_function();
someObj.addEventListener("click", function(){
    some_function(someVar);
}, false);

The problem is that the value of someVar is not visible inside the listener function of the addEventListener, where it is probably being treated as a new variable.

SnareChops
  • 13,175
  • 9
  • 69
  • 91
Abhishek Yadav
  • 4,931
  • 4
  • 20
  • 10
  • 15
    A very clear article on the matter: http://toddmotto.com/avoiding-anonymous-javascript-functions/ – Aurelio May 28 '14 at 14:57
  • Not the cleanest way, but does the job. Note that if someVar could only be digit or text: eval('someObj.addEventListener("click",function(){some_function('+someVar+');});'); – Ignas2526 Jun 27 '14 at 16:37
  • Just had this issue today - solution given here is correct (other solutions have issues like for loop issue, etc.) - https://stackoverflow.com/a/54731362/984471 – Manohar Reddy Poreddy Oct 20 '19 at 05:00

36 Answers36

514

Why not just get the arguments from the target attribute of the event?

Example:

const someInput = document.querySelector('button');
someInput.addEventListener('click', myFunc, false);
someInput.myParam = 'This is my parameter';
function myFunc(evt)
{
  window.alert(evt.currentTarget.myParam);
}
<button class="input">Show parameter</button>

JavaScript is a prototype-oriented language, remember!

René K
  • 337
  • 5
  • 14
Zaloz
  • 5,253
  • 1
  • 13
  • 2
  • 38
    This is the correct answer becouse it let us to use after the 'removeEventListener' function. – user5260143 Dec 04 '16 at 12:52
  • 23
    Shouldn't it be `evt.currentTarget.myParam`? If there is another element inside the 'someInput', the `evt.target` may be refer to the inner element. (https://jsfiddle.net/qp5zguay/1/) – Herbertusz Jan 24 '17 at 19:58
  • This preserves `this`! Using this method in typescript requires the element to be `any` or to make a sub type though. – Old Badman Grey Apr 06 '17 at 01:49
  • someInput.setAttribute("class", "democlass"); – bh_earth0 Dec 28 '17 at 14:57
  • 3
    My variables keep coming back as undefined... any thoughts on how to fix that? – nomaam Sep 05 '18 at 01:48
  • This is the correct answer, and it is even the method jQuery uses to pass arguments. Except they store it in evt.data.myParam, but close enough. – beliha Mar 26 '19 at 07:59
  • 5
    If `addEventListener` is for `document`, `evt.target.myParam` didn't work for me. I had to use `evt.currentTarget.myParam` instead. – turrican_34 Jul 08 '19 at 18:15
  • 2
    it's not advisable to add custom/additional attribute to DOMElement – Velaro Feb 10 '22 at 15:33
  • But the parameter of a DOM element is a string, right? What if I want my data to be an object? Do I have to go through `JSON.parse`? – Tim Erickson Apr 03 '22 at 04:59
  • I think that this is bad approach, we should not pollute element's interface. It so not obvious for other developers where parameters come from either. – Eduardo Aug 02 '22 at 12:42
293

There is absolutely nothing wrong with the code you've written. Both some_function and someVar should be accessible, in case they were available in the context where anonymous

function() { some_function(someVar); } 

was created.

Check if the alert gives you the value you've been looking for, be sure it will be accessible in the scope of anonymous function (unless you have more code that operates on the same someVar variable next to the call to addEventListener)

var someVar; 
someVar = some_other_function();
alert(someVar);
someObj.addEventListener("click", function(){
    some_function(someVar);
}, false);
Tolga Evcimen
  • 7,112
  • 11
  • 58
  • 91
Sergey Ilinsky
  • 31,255
  • 9
  • 54
  • 56
  • 114
    This doesn't work in for loop. I always get the latest value and not the one which belonged to that iteration. Any solution? – iMatoria Jun 25 '11 at 17:19
  • 7
    Anybody knows why it doesn't work in loop? What's the reason of that behaviour? – Morfidon May 15 '15 at 01:23
  • 3
    @Morfidon because the function with global variables act as [closures](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures) in javascript which means they remembers the environment outside their lexical scope . If you just create different function in same environment then they will reference to same environment. – bugwheels94 May 20 '15 at 15:58
  • 28
    @Morfidon: In a loop, the value of someVar is not the value it had when the listener was added, but the value it has when the listener is executed. When the listener is executed, the loop has already ended, so the value of someVar will be the value it had when the loop ended. – www.admiraalit.nl Oct 29 '15 at 16:45
  • 5
    This is not correct answer becouse it not let us to use the 'removeEventListener' function after. – user5260143 Dec 04 '16 at 12:52
  • @ankitbug94 How could one put `someVar` into `Lexical scope` so the current value can be used inside the event? jQuery solve the problem using `event.data` http://api.jquery.com/event.data/ but how do we do it without jQuery? – Luke T O'Brien Jun 22 '17 at 09:10
  • 8
    @iMatoria I have just discovered that creating a `bound function` using the `.bind()` method will solve the issue with loops https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bind – Luke T O'Brien Jun 22 '17 at 09:46
  • 1
    @LukeTO'Brien Sorry for so delayed response. If you still want to know, you can always use [partial functions using currying](https://www.sitepoint.com/currying-in-functional-javascript/) which creates and returns new function with their own lexical scope. You may find this extremely helpful https://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example – bugwheels94 Jun 29 '17 at 19:02
  • @Morfidon see my answer below for something that works with loops. – Hello World Nov 23 '17 at 10:22
  • @NeonWarge: Please compare the profiles before such hard advice. If you are a SEO expert then you should know that links get dead and an outsider doesn't control it. A polite way could had been to inform about the dead link and/or suggest a correction. – iMatoria Apr 22 '18 at 03:47
  • when it enters the `some_function`, the `someVar` may already has nothing referencing itself and already got cleaned in the callstack frame. – ROROROOROROR Jul 25 '18 at 04:54
  • What if the listener is register within a `mycustom` function, and the callback need to reuse some variable from the `mycustom` function PLUS I want make the callback as a `customHandler` global function instead of annonymous callback function? How do i pass the variable from `mycustom` function to the `customHandler` global function? – Jerry Jan 12 '20 at 15:48
  • Late answer to an old question, but since (I think) ES6, you can use `let` instead of `var`, and it will work inside loops, because `let` has block scope whereas `var` will be subject to hoisting. – KWallace Apr 01 '21 at 19:50
121

This question is old but I thought I'd offer an alternative using ES5's .bind() - for posterity. :)

function some_func(otherFunc, ev) {
    // magic happens
}
someObj.addEventListener("click", some_func.bind(null, some_other_func), false);

Just be aware that you need to set up your listener function with the first param as the argument you're passing into bind (your other function) and the second param is now the event (instead of the first, as it would have been).

HoldOffHunger
  • 18,769
  • 10
  • 104
  • 133
Brian Moore
  • 1,588
  • 1
  • 9
  • 10
  • 2
    [Function.prototype.bind()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind) is really the best way to solve this issue. Plus it works intuitively inside loops—you get the lexical scope you want. No anonymous functions, [IIFEs](https://developer.mozilla.org/en-US/docs/Glossary/IIFE), or special properties tacked on to objects. – Clint Pachl Mar 11 '18 at 10:14
  • See the pros and cons of [IIFE vs bind()](https://stackoverflow.com/q/36747209/41906). – Clint Pachl Mar 11 '18 at 10:17
  • 13
    By using `Function.prototype.bind()` you can't [remove the event listener](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener), better to use a currying function instead (see @tomcek112 answer) – pldg Sep 17 '19 at 16:01
  • NOTE: `some_other_func` is a variable, you can pass whatever value you want to `some_func`. – hitautodestruct Jan 07 '20 at 19:41
  • Any reference for the event to be the last param? – Dante Dec 06 '22 at 15:04
83

Quite and old question but I had the same issue today. Cleanest solution I found is to use the concept of currying.

The code for that:

someObj.addEventListener('click', some_function(someVar));

var some_function = function(someVar) {
    return function curried_func(e) {
        // do something here
    }
}

By naming the curried function it allows you to call Object.removeEventListener to unregister the eventListener at a later execution time.

Matthew Brent
  • 1,366
  • 11
  • 23
tomcek112
  • 1,516
  • 10
  • 16
  • 8
    Glad to encounter this answer mentioning curried function. How would you remove event listener though? – bob Sep 24 '17 at 15:43
  • 4
    Awesome to see good terminology. You should be able to remove the event listener by naming the curried function. i'll propose an edit. – Matthew Brent May 01 '18 at 15:16
  • 1
    This answer will register the function as many times as addEventListener is called, since some_function (var) is returning a newly created function every time. – Yahia Jun 25 '19 at 07:27
  • 2
    i dont like the idea of having to name the curried function in order to remove the listener cuz then ur dealing with 2 diff namespaces that u gotta keep track of – oldboy Nov 19 '19 at 00:24
  • how to use an arrow function for the curried fn? – Kenzo Oct 23 '20 at 18:17
  • This does not work for me, since the `curried_func` is not accessible outside of `some_function`. What fails is doing this: `someObj.removeEventListener('click', curried_func);`. Maybe I misinterpreted your answer somehow. – martin36 Mar 23 '21 at 14:39
  • this should be the accepted answer! concept is on point! – Guga Figueiredo Apr 10 '21 at 12:05
  • @Kenzo, var some_function = function (params) { return (e) => {...} } – Guga Figueiredo Apr 10 '21 at 12:19
  • 2
    @martin36 notice the durrying structure, you have a `currying function` and a `curried function`. You should add and remove the currying function as evente listener. in @tomeck112's example, that is `some_function` – Guga Figueiredo Apr 10 '21 at 12:20
  • Does it mean that I remove the listener by `removeEventListener('click', some_function(someVar))`? But what if I don't have `someVar` where I want to remove the listener? – Halfist Jan 17 '22 at 14:27
  • This answer helped me to remove the eventListener correctly. You need to memorize created curried function: https://stackoverflow.com/questions/55650739/how-to-remove-event-listener-with-currying-function – Catch Sep 29 '22 at 08:13
47

You can just bind all necessary arguments with 'bind':

root.addEventListener('click', myPrettyHandler.bind(null, event, arg1, ... ));

In this way you'll always get the event, arg1, and other stuff passed to myPrettyHandler.

http://passy.svbtle.com/partial-application-in-javascript-using-bind

Oleksandr Tkalenko
  • 1,098
  • 11
  • 23
41

nice one line alternative

element.addEventListener('dragstart',(evt) => onDragStart(param1, param2, param3, evt));
function onDragStart(param1, param2, param3, evt) {

 //some action...

}
Gon82
  • 409
  • 5
  • 5
26

You can add and remove eventlisteners with arguments by declaring a function as a variable.

myaudio.addEventListener('ended',funcName=function(){newSrc(myaudio)},false);

newSrc is the method with myaudio as parameter funcName is the function name variable

You can remove the listener with myaudio.removeEventListener('ended',func,false);

BBog
  • 3,630
  • 5
  • 33
  • 64
Ganesh Krishnan
  • 369
  • 3
  • 6
19

Function.prototype.bind() is the way to bind a target function to a particular scope and optionally define the this object within the target function.

someObj.addEventListener("click", some_function.bind(this), false);

Or to capture some of the lexical scope, for example in a loop:

someObj.addEventListener("click", some_function.bind(this, arg1, arg2), false);

Finally, if the this parameter is not needed within the target function:

someObj.addEventListener("click", some_function.bind(null, arg1, arg2), false);
Clint Pachl
  • 10,848
  • 6
  • 41
  • 42
eclos
  • 201
  • 2
  • 2
18

You could pass somevar by value(not by reference) via a javascript feature known as closure:

var someVar='origin';
func = function(v){
    console.log(v);
}
document.addEventListener('click',function(someVar){
   return function(){func(someVar)}
}(someVar));
someVar='changed'

Or you could write a common wrap function such as wrapEventCallback:

function wrapEventCallback(callback){
    var args = Array.prototype.slice.call(arguments, 1);
    return function(e){
        callback.apply(this, args)
    }
}
var someVar='origin';
func = function(v){
    console.log(v);
}
document.addEventListener('click',wrapEventCallback(func,someVar))
someVar='changed'

Here wrapEventCallback(func,var1,var2) is like:

func.bind(null, var1,var2)
ahuigo
  • 2,929
  • 2
  • 25
  • 45
  • 3
    Thanks a lot for this answer ! The OP was not looking for this, but I think people who type "How to pass args to addEventListener" into google will be looking for your answer. It just needs a bit more explanation :) I'm editing it. – Sindarus Aug 10 '16 at 17:50
13

Here's yet another way (This one works inside for loops):

var someVar = some_other_function();
someObj.addEventListener("click", 

function(theVar){
    return function(){some_function(theVar)};
}(someVar),

false);
Hello World
  • 925
  • 7
  • 18
11

someVar value should be accessible only in some_function() context, not from listener's. If you like to have it within listener, you must do something like:

someObj.addEventListener("click",
                         function(){
                             var newVar = someVar;
                             some_function(someVar);
                         },
                         false);

and use newVar instead.

The other way is to return someVar value from some_function() for using it further in listener (as a new local var):

var someVar = some_function(someVar);
Thevs
  • 3,189
  • 2
  • 20
  • 32
11

one easy way to execute that may be this

    window.addEventListener('click', (e) => functionHandler(e, ...args));

Works for me.

8
    $form.addEventListener('submit', save.bind(null, data, keyword, $name.value, myStemComment));
    function save(data, keyword, name, comment, event) {

This is how I got event passed properly.

chovy
  • 72,281
  • 52
  • 227
  • 295
  • Excellent, this is how I was almost concluding - just wrongly passed extra event in bind when it is not there (like in angular), which automatically comes in this case. – Manohar Reddy Poreddy Oct 20 '19 at 04:59
  • Yeah, this works. Thanks. What's the null in the first argument? And how can I also pass this object for binding? – Rishabh Gupta Jul 31 '20 at 11:19
7

Use

   el.addEventListener('click',
    function(){
        // this will give you the id value 
        alert(this.id);    
    },
false);

And if you want to pass any custom value into this anonymous function then the easiest way to do it is

 // this will dynamically create property a property
 // you can create anything like el.<your  variable>
 el.myvalue = "hello world";
 el.addEventListener('click',
    function(){
        //this will show you the myvalue 
        alert(el.myvalue);
        // this will give you the id value 
        alert(this.id);    
    },
false);

Works perfectly in my project. Hope this will help

BBog
  • 3,630
  • 5
  • 33
  • 64
kta
  • 19,412
  • 7
  • 65
  • 47
  • Yes, definitely helped, as it also maintained the expected scope within a `for` loop. – j4v1 Mar 25 '20 at 18:34
7

If I'm not mistaken using calling the function with bind actually creates a new function that is returned by the bind method. This will cause you problems later or if you would like to remove the event listener, as it's basically like an anonymous function:

// Possible:
function myCallback() { /* code here */ }
someObject.addEventListener('event', myCallback);
someObject.removeEventListener('event', myCallback);

// Not Possible:
function myCallback() { /* code here */ }
someObject.addEventListener('event', function() { myCallback });
someObject.removeEventListener('event', /* can't remove anonymous function */);

So take that in mind.

If you are using ES6 you could do the same as suggested but a bit cleaner:

someObject.addEventListener('event', () => myCallback(params));
developer82
  • 13,237
  • 21
  • 88
  • 153
  • 1
    but that's an anonymous function in the ES6 example, no? could solve by binding the function and assigning it to a different variable. can then use `removeEventListener('event', someDifferentBoundedFunction)` – NickW Jan 17 '22 at 17:07
5

One way is doing this with an outer function:

elem.addEventListener('click', (function(numCopy) {
  return function() {
    alert(numCopy)
  };
})(num));

This method of wrapping an anonymous function in parentheses and calling it right away is called an IIFE (Immediately-Invoked Function Expression)

You can check an example with two parameters in http://codepen.io/froucher/pen/BoWwgz.

catimg.addEventListener('click', (function(c, i){
  return function() {
    c.meows++;
    i.textContent = c.name + '\'s meows are: ' + c.meows;
  }
})(cat, catmeows));
Felipe
  • 51
  • 1
  • 1
5

In 2019, lots of api changes, the best answer no longer works, without fix bug.

share some working code.

Inspired by all above answer.

 button_element = document.getElementById('your-button')

 button_element.setAttribute('your-parameter-name',your-parameter-value);

 button_element.addEventListener('click', your_function);


 function your_function(event)
   {
      //when click print the parameter value 
      console.log(event.currentTarget.attributes.your-parameter-name.value;)
   }
hoogw
  • 4,982
  • 1
  • 37
  • 33
4

Sending arguments to an eventListener's callback function requires creating an isolated function and passing arguments to that isolated function.

Here's a nice little helper function you can use. Based on "hello world's" example above.)

One thing that is also needed is to maintain a reference to the function so we can remove the listener cleanly.

// Lambda closure chaos.
//
// Send an anonymous function to the listener, but execute it immediately.
// This will cause the arguments are captured, which is useful when running 
// within loops.
//
// The anonymous function returns a closure, that will be executed when 
// the event triggers. And since the arguments were captured, any vars 
// that were sent in will be unique to the function.

function addListenerWithArgs(elem, evt, func, vars){
    var f = function(ff, vv){
            return (function (){
                ff(vv);
            });
    }(func, vars);

    elem.addEventListener(evt, f);

    return f;
}

// Usage:

function doSomething(withThis){
    console.log("withThis", withThis);
}

// Capture the function so we can remove it later.
var storeFunc = addListenerWithArgs(someElem, "click", doSomething, "foo");

// To remove the listener, use the normal routine:
someElem.removeEventListener("click", storeFunc);
bob
  • 7,539
  • 2
  • 46
  • 42
  • This answer is from '15 but it's exactly what I needed to handle this issue with using a useRef hook. If you're using a ref hook and needed a listener for it that you can clean up on component unmounting, this is it. The 4th arg to `storeFunc` should be your ref variable. Put your listener removal in a useEffect like this and you're good to go: `useEffect(() => { return () => { window.removeEventListener('scroll', storeFunc, false); } }, [storeFunc])` – Rob B Sep 05 '19 at 14:48
2

There is a special variable inside all functions: arguments. You can pass your parameters as anonymous parameters and access them (by order) through the arguments variable.

Example:

var someVar = some_other_function();
someObj.addEventListener("click", function(someVar){
    some_function(arguments[0]);
}, false);
StanE
  • 2,704
  • 29
  • 38
  • Hmm... What's the reason for the downvote? If it was not what you where looking for, then please explain more clearly what you mean (I know that the question has been answered already). But isn't my code answering what you asked for? The special variable "arguments" gives you access to all parameters inside a function. – StanE Mar 02 '15 at 23:07
2

I was stuck in this as I was using it in a loop for finding elements and adding listner to it. If you're using it in a loop, then this will work perfectly

for (var i = 0; i < states_array.length; i++) {
     var link = document.getElementById('apply_'+states_array[i].state_id);
     link.my_id = i;
     link.addEventListener('click', function(e) {   
        alert(e.target.my_id);        
        some_function(states_array[e.target.my_id].css_url);
     });
}
Suneel Kumar
  • 5,621
  • 3
  • 31
  • 44
2

Since your event listener is 'click', you can:

someObj.setAttribute("onclick", "function(parameter)");
Michael
  • 29
  • 1
2

I suggest you to do something like that:

var someVar = some_other_function();
someObj.addEventListener("click", (event, param1 = someVar) => {
    some_function(param1);
}, false);
Elikill58
  • 4,050
  • 24
  • 23
  • 45
leafsAsd
  • 21
  • 2
  • That’s not a very clean way. This is reminiscent of [code golfing](//codegolf.stackexchange.com/a/2714/42589). It’s also not future-proof: what if the DOM specification extends `addEventListener` in the future to call the event listener with a second argument? Then this will stop working. – Sebastian Simon Feb 03 '22 at 10:50
2

The PERFECT SOLUTION for this is to use Closures like this:

function makeSizer(size) {
  return function () {
    document.body.style.fontSize = `${size}px`;
  };
}

//pass parameters here and keep the reference in variables:
const size12 = makeSizer(12);
const size24 = makeSizer(24);
const size36 = makeSizer(36);

document.getElementById('size-12').addEventListener("click", size12);
document.getElementById('size-24').addEventListener("click", size24);
document.getElementById('size-36').addEventListener("click", size36);

document.getElementById('remove-12').addEventListener("click", ()=>{
    document.getElementById('size-12').removeEventListener("click", size12);
  alert("Now click on 'size 12' button and you will see that there is no event listener any more");
});
test<br/>
<button id="size-12">
size 12
</button>

<button id="size-24">
size 24
</button>

<button id="size-36">
size 36
</button>

<button id="remove-12">
remove 12
</button>

So basically you wrap a function inside another function and assign that to a variable that you can register as an event listener, but also unregister as well!

Dejan Dozet
  • 948
  • 10
  • 26
1

The following answer is correct but the below code is not working in IE8 if suppose you compressed the js file using yuicompressor. (In fact,still most of the US peoples using IE8)

var someVar; 
someVar = some_other_function();
alert(someVar);
someObj.addEventListener("click",
                         function(){
                          some_function(someVar);
                         },
                         false);

So, we can fix the above issue as follows and it works fine in all browsers

var someVar, eventListnerFunc;
someVar = some_other_function();
eventListnerFunc = some_function(someVar);
someObj.addEventListener("click", eventListnerFunc, false);

Hope, it would be useful for some one who is compressing the js file in production environment.

Good Luck!!

Asik
  • 7,967
  • 4
  • 28
  • 34
1
    var EV = {
        ev: '',
        fn: '',
        elem: '',
        add: function () {
            this.elem.addEventListener(this.ev, this.fn, false);
        }
    };

    function cons() {
        console.log('some what');
    }

    EV.ev = 'click';
    EV.fn = cons;
    EV.elem = document.getElementById('body');
    EV.add();

//If you want to add one more listener for load event then simply add this two lines of code:

    EV.ev = 'load';
    EV.add();
1

The following approach worked well for me. Modified from here.

function callback(theVar) {
  return function() {
    theVar();
  }
}

function some_other_function() {
  document.body.innerHTML += "made it.";
}

var someVar = some_other_function;
document.getElementById('button').addEventListener('click', callback(someVar));
<!DOCTYPE html>
<html>
  <body>
    <button type="button" id="button">Click Me!</button>
  </body>
</html>
Nate
  • 2,449
  • 3
  • 21
  • 29
1

Another workaround is by Using data attributes

function func(){
    console.log(this.dataset.someVar);
    div.removeEventListener("click", func);
}
    
var div = document.getElementById("some-div");
div.setAttribute("data-some-var", "hello");
div.addEventListener("click", func);

jsfiddle

Cody Tookode
  • 862
  • 12
  • 22
1

Also try these (IE8 + Chrome. I dont know for FF):

function addEvent(obj, type, fn) {
    eval('obj.on'+type+'=fn');
}

function removeEvent(obj, type) {
    eval('obj.on'+type+'=null');
}

// Use :

function someFunction (someArg) {alert(someArg);}

var object=document.getElementById('somObject_id') ;
var someArg="Hi there !";
var func=function(){someFunction (someArg)};

// mouseover is inactive
addEvent (object, 'mouseover', func);
// mouseover is now active
addEvent (object, 'mouseover');
// mouseover is inactive

Hope there is no typos :-)

DMike92
  • 25
  • 3
0

The following code worked fine for me (firefox):

for (var i=0; i<3; i++) {
   element = new ...   // create your element
   element.counter = i;
   element.addEventListener('click', function(e){
        console.log(this.counter);
        ...            // another code with this element
   }, false);
}

Output:

0
1
2
Enamul Hassan
  • 5,266
  • 23
  • 39
  • 56
Šerg
  • 793
  • 5
  • 18
0

You need:

newElem.addEventListener('click', {
    handleEvent: function (event) {
        clickImg(parameter);
    }
});
Victor Behar
  • 740
  • 6
  • 9
0

Probably not optimal, but simple enough for those not super js savvy. Put the function that calls addEventListener into its own function. That way any function values passed into it maintain their own scope and you can iterate over that function as much as you want.

Example I worked out with file reading as I needed to capture and render a preview of the image and filename. It took me awhile to avoid asynchronous issues when utilizing a multiple file upload type. I would accidentally see the same 'name' on all renders despite uploading different files.

Originally, all the readFile() function was within the readFiles() function. This caused asynchronous scoping issues.

    function readFiles(input) {
      if (input.files) {
        for(i=0;i<input.files.length;i++) {

          var filename = input.files[i].name;

          if ( /\.(jpe?g|jpg|png|gif|svg|bmp)$/i.test(filename) ) {
            readFile(input.files[i],filename);
          }
       }
      }
    } //end readFiles



    function readFile(file,filename) {
            var reader = new FileReader();

            reader.addEventListener("load", function() { alert(filename);}, false);

            reader.readAsDataURL(file);

    } //end readFile
Spoo
  • 205
  • 1
  • 4
0

just would like to add. if anyone is adding a function which updates checkboxes to an event listener, you would have to use event.target instead of this to update the checkboxes.

Bruce Tong
  • 1,366
  • 15
  • 14
0

In case you want to remove the event-listener later, creating a reference to a currying function is a good alternative.

In the code below, I will illustrate what I mean.

// This is the curry function. We return a new function with the signature of what the click-listener expects
const handleClick = (foo, bar) => (clickEvent) => {
  console.log('we get our custom input', foo, bar);
  console.log('we get the click event too', clickEvent);
}

// We need to store a reference to the listener, making sure we are removing the correct reference later
const myListener = handleClick('foo', 'bar'); // Remember that we now return the actual event-handler


const btn = document.getElementById('btn'); // find the element to attach the listener to
btn.addEventListener('click', myListener);

// remove the event listener like this by using our reference
btn.removeEventListener('click', myListener);

Here's a working example on CodePen

John
  • 10,165
  • 5
  • 55
  • 71
-1

Other alternative, perhaps not as elegant as the use of bind, but it is valid for events in a loop

for (var key in catalog){
    document.getElementById(key).my_id = key
    document.getElementById(key).addEventListener('click', function(e) {
        editorContent.loadCatalogEntry(e.srcElement.my_id)
    }, false);
}

It has been tested for google chrome extensions and maybe e.srcElement must be replaced by e.source in other browsers

I found this solution using the comment posted by Imatoria but I cannot mark it as useful because I do not have enough reputation :D

Community
  • 1
  • 1
fhuertas
  • 4,764
  • 2
  • 17
  • 28
-1

I have very simplistic approach. This may work for others as it helped me. It is... When you are having multiple elements/variables assigned a same function and you want to pass the reference, the simplest solution is...

function Name()
{

this.methodName = "Value"

}

That's it. It worked for me. So simple.

AAYUSH SHAH
  • 131
  • 2
  • 6
-2

This solution may good for looking

var some_other_function = someVar => function() {
}

someObj.addEventListener('click', some_other_function(someVar));

or bind valiables will be also good

fnclovers
  • 119
  • 9