[Greasemonkey] addEventListener inside loop
Jeremy Dunck
jdunck at gmail.com
Wed Feb 1 06:13:59 EST 2006
On 1/31/06, Daniel Hood <danhood at gmail.com> wrote:
> I'm have a bit of trouble with some code involving looping over some
> range and adding event listeners to elements. It seems that the
> variables referenced in the anonymous function being bound to that
> event don't have the state of the loop variable at the time of
> binding, but rather the value once the loop has completed. This is a
> much simplified case of the problem I am experiencing, but it
> illustrates the point. I believe that this can be solved via a
> closure, but I don't seem to be having any luck.
>
Actually, you're creating a closure on accident, which is causing your
trouble. :)
But you're doing well to understand the problems clearly.
Arvid's suggestion is good because it binds the current value of the
loop variable i to a local variable i in foo.
This would be clearer if he hadn't named the foo-local variable i.
> function do_stuff() {
> for(i = 1; i <= 3; i++) {
> document.getElementById("button" +
> i).addEventListener("click", function() { alert(i); }, false);
> }
> }
So, when that anonymous function is created, JS stores the lexical
scope, which includes do_stuff, on the function object. Later, when
you refer to i, JS climbs the scope chain and finds do_stuff.<var
obj>.i, which by then has the loop-exit value.
In Arvid's example (I'll change the param name):
function foo(K) {
return function () {
alert(K);
}
}
button.addEventListener("click", foo(i), false);
What's going on here is the that loop variable's value is passed to
the local variable K, and the returned inner function then binds its K
to foo.<var obj>.K.
This does what you want because K is initially set to the value you
want, and never changed.
-Jeremy
More information about the Greasemonkey
mailing list