admin 管理员组文章数量: 1086019
Interactive map with buttons in the shape of states, each button has the state abbreviation as an id, when a button/state is clicked I would like to fire the function "stateSelect" and send the state abbreviation with it so I know what's been pressed. Why doesn't the following work?
var stateList = new Array("AK","AL","AR","AS","AZ","CA","CO","CT","DC","DE","FL","GA","GU","HI","IA","ID",
"IL","IN","KS","KY","LA","MA","MD","ME","MH","MI","MN","MO","MS","MT","NC","ND","NE","NH","NJ","NM","NV","NY",
"OH","OK","OR","PA","PR","PW","RI","SC","SD","TN","TX","UT","VA","VI","VT","WA","WI","WV","WY");
for (var i = 0; i < stateList.length; i++) {
document.getElementById(stateList[i]).addEventListener('mousedown', function() {stateSelect(stateList[i])}, false);
}
I obviously want to avoid 50 some lines of code but I'm not sure why this simple loop isn't working.
Interactive map with buttons in the shape of states, each button has the state abbreviation as an id, when a button/state is clicked I would like to fire the function "stateSelect" and send the state abbreviation with it so I know what's been pressed. Why doesn't the following work?
var stateList = new Array("AK","AL","AR","AS","AZ","CA","CO","CT","DC","DE","FL","GA","GU","HI","IA","ID",
"IL","IN","KS","KY","LA","MA","MD","ME","MH","MI","MN","MO","MS","MT","NC","ND","NE","NH","NJ","NM","NV","NY",
"OH","OK","OR","PA","PR","PW","RI","SC","SD","TN","TX","UT","VA","VI","VT","WA","WI","WV","WY");
for (var i = 0; i < stateList.length; i++) {
document.getElementById(stateList[i]).addEventListener('mousedown', function() {stateSelect(stateList[i])}, false);
}
I obviously want to avoid 50 some lines of code but I'm not sure why this simple loop isn't working.
Share Improve this question asked Jun 19, 2011 at 3:23 StephenStephen 672 silver badges5 bronze badges2 Answers
Reset to default 5Because when the handler runs, it looks up the value of i
, which is wherever it was after the loop finished.
You need to scope the i
variable in a function:
function listenerForI( i ) {
document.getElementById(stateList[i]).addEventListener('mousedown', function() {stateSelect(stateList[i])}, false);
}
for (var i = 0; i < stateList.length; i++) {
listenerForI( i );
}
Now the i
referenced by the handler will be the parameter to the listenerForI
function that was invoked. As such, that i
will reference the value that was passed in from the for
loop.
You have a scoping issue. Javascript is not block-scoped; it is function-scoped. Basically, you must create a new function whenever you wish to create a new variable in a loop.
The most elegant way to do so is as follows:
stateList.map(function(abbrev){
$(abbrev).mousedown(function(){stateSelect(abbrev)});
});
If you are not using jQuery, merely replace $(abbrev).mousedown
with document.getElementById(abbrev).addEventListener
.
(Just to preempt the people who go "map isn't standard"; it is in the javascript ECMA-262 standard 5th edition which has support from all browser vendors. If one is paranoid about supporting older browsers, one can just $.map
.)
Here is how one would do so using a for
loop; it's a bit uglier but it demonstrates the necessity of creating new closures via functions:
for(var i=0; i<stateList.length; i++)
(function(i){
$(stateList[i]).mousedown(...);
})(i);
Like I said, a bit uglier than necessary; you could also do this which is slightly less ugly, but is basically the same thing:
function createListener(abbrev) {
$(abbrev).mousedown(...);
}
for(var i=0; i<stateList.length; i++)
createListener(stateList[i]);
本文标签: Javascript Array addEventListenerStack Overflow
版权声明:本文标题:Javascript Array addEventListener - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://roclinux.cn/p/1744057646a2526141.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论