Can't pass event to addEventListener: closure issue

23,529

The event will be passed to your function automatically—just make it the first argument to the function you pass to addEventListener. Also, false is the default value for the capture parameter.

(function() {
    var i = month;
    shape.addEventListener("mouseover", function(e) { popup_on(e, foo, i); });
})();

Also, are you ok with foo being closed over in your event callback? If not, you could do the same thing with it

(function() {
    var i = month;
    var f = foo;
    shape.addEventListener("mouseover", function(e) { popup_on(e, f, i); });
})();

And if all these local variables are getting annoying, you can make them parameters to possibly make things a bit more tidy

(function(i, f) {
    shape.addEventListener("mouseover", function(e) { popup_on(e, f, i); });
})(month, foo);
Share:
23,529
EML
Author by

EML

Electronic Engineer and self-employed consultant, Physics degree, working in VHDL, Verilog, and C++, primarily in FPGA and ASIC design. I've written two compilers, including one which generates Verilog (9-pass, about 50K lines of C++). I'll add VHDL output if/when I get some spare time. I also have experience in SystemC and Specman/'e'. I occasionally write JavaScript, and odd bits of HTML/PHP/Ajax, when I've got nothing better to do, primarily to generate and display SVG images. Always looking for new opportunities - mail me if you want to discuss anything; I'm on sa212+stackoverflow at cyconix dotcom.

Updated on January 04, 2020

Comments

  • EML
    EML over 4 years

    This one's driving me crazy... I have a loop which adds an event listener to an SVG object. The object is, for the sake of argument, a small circle, and I have to add mouseover and mouseout events for each of the 10 circles.

    My first problem is the standard closure-scope thing - because all the listeners are added in the same loop, they all see the same invalid value of the loop variable. I can fix this, I think, but the second problem is that I have to pass 'event' to the listeners, and I can't find any way to fix both these issues simultaneously.

    I've tried various versions of this:

    for(month = 0; month < nMonths; month++) {
       ...
       shape.addEventListener(
         "mouseover", 
         (function(event, index) { popup_on(event, foo, index); })(event, month),
         false);
       group.appendChild(shape);
    }
    

    This particular version gives me 'event is not defined'. popup_on is the real handler, and must get event and the current value of month. Any idea how I should be doing this? Thanks.

  • EML
    EML over 12 years
    Sorry to be so dumb, but where do I actually put this function? 'shape' is created in a loop, maybe 10 or 20 times over, and each new instance of 'shape' (from 'createElementNS') has to have a handler attached to it. So there doesn't seem to be anywhere where I can put this anonymous function where the current 'shape' is in context? Given this, don't I have to put everything in the 'addEventListener' call itself? Which, I think, leaves the problem of how I can get both 'e' and 'month' in as params...?
  • Adam Rackis
    Adam Rackis over 12 years
    @user785194 I think the code I put above will work fine. Each time shape is re-created, just put the code above in there to add the event listener to that particular instance.
  • EML
    EML over 12 years
    Brilliant - that did it. Thanks.