5 ms·
Please do.
by Wilduck 16y ago
Please do.
- deleted 16y ago[deleted]
- theoretical 16y agoIt won't alert quite what you want - when you click on each element in the list, it will alert "4". This is because the function assigned to the click event of each li is bound to the "i" variable used in the loop by a closure. Variable i is incremented to 4 before the loop ends, so that is what each will print. You could use make the function used in the click handler take a parameter, then use partial function application (or currying) to fix the value of the parameter.
- Timmy_C 16y agoThe function in the click handler does take a parameter 'e' (...or whatever you call it) which is an Event object. But I think you're on to something by using currying.
- theoretical 16y agoWell yes, the function is called with a MouseEvent as one of the arguments, so you could use the "arguments" object to access it. What I was thinking of, was something along the lines of: // From http://ejohn.org/blog/partial-functions-in-javascript/ Function.prototype.curry = function() { var fn = this, args = Array.prototype.slice.call(arguments); return function() { return fn.apply(this, args.concat( Array.prototype.slice.call(arguments))); }; }; els = document.getElementsByTagName('li'); for(i=0; i < els.length; i++){ els[i].addEventListener('click', function(x){ alert(x); }.curry(i), false); }
- robterrell 16y agoWrap the line of code inside the loop inside another function, which will have the effect of binding the iterator i to the desired value before the event handler anonymous function is created.
- lhorie 16y agothis is what I usually tell people to do: var els = document.getElementsByTagName('li');//use var unless you really really really meant global for(var i=0; i < els.length; i++){ (function(i) {//creates new scope for each iteration els[i].addEventListener('click', function(){alert(i);}, false); })(i); }
- aaronblohowiak 16y agoi agree with the choice of code, but I have a different style for laying out the code. i dislike the declaration and immediate execution of an anonymous function. i much prefer to give it a name, move it out of the loop itself and then call it within the loop. it makes reading the code more top-to-bottom. with this approach, when I get to the anon func declaration, i have to scan down looking for when it is invoked. while indentation helps, i then have to backtrack up to the beginning of the func declaration.. and hopefully i haven't lost track of what the execution context for the anon func is and so forth...
- lhorie 16y agoI don't generally care too much to talk about style when the problem at hand is that someone has been banging their head against the desk for the past two hours and they just want it to work (and, in my experience, this usually is the case, for some reason) But yeah, if we're gonna be super nitpicky, yeah sure, improve the for loop also, while we're at it. for (var i = -1; els[++i];) {//given the code in the loop body, this is shorter and faster