There are two versions, supposedly when the user click the first link, it will alert "1", and the second link, "2", etc.:
Version 1:
<a href="#" id="link1">click me</a>
<a href="#" id="link2">click me</a>
<a href="#" id="link3">click me</a>
<a href="#" id="link4">click me</a>
<a href="#" id="link5">click me</a>
<script type="text/javascript">
for (i = 1; i <= 5; i++) {
document.getElementById('link' + i).onclick = (function() {
return function() {
var n = i;
alert(n);
return false;
}
})();
}
</script>
Version 2:
<a href="#" id="link1">click me</a>
<a href="#" id="link2">click me</a>
<a href="#" id="link3">click me</a>
<a href="#" id="link4">click me</a>
<a href="#" id="link5">click me</a>
<script type="text/javascript">
for (i = 1; i <= 5; i++) {
document.getElementById('link' + i).onclick = (function() {
var n = i;
return function() {
alert(n);
return false;
}
})();
}
</script>
Version 1 will not work. Version 2 will. I think I know the reason why, but would like to compare with other people's explanations as to why version 1 doesn't work.
Version 1 does not work because there's a common variable "i" (a global variable in this case, because you forgot var
) that is shared by every "click" handler function the loop creates.
In the second version, you create a new lexical scope with the little wrapper function. That gives each "click" handler it's very own private "i".
In the second example you create a var n = i;
it makes i
value scoped inside the onclick function. While at the first one the onclick function still uses global value of i
I'd suggest this usage instead:
for (i = 1; i <= 5; i++) {
document.getElementById('link' + i).onclick = (function(i) {
return function() {
alert(i);
return false;
}
})(i);
}
In this case you'll get the same behaviour since i
will be the local variable for onclick function as it's an argument.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With