PDA

View Full Version : [RESOLVED] looping + event binding = "freezing" a variable?


robkar97
12-22-2008, 12:06 PM
How do I make these divs alert "0", "1" or "2" when clicked - not simply "2" all the times?


<html>
<body onload="bindEvents()">

<script type="text/javascript">

function bindEvents(){
var elements = new Array('zero', 'one', 'two');
for (var i in elements) {
document.getElementById(elements[i]).onclick = function(){alert(i)}
}
}
</script>


<div id="zero">My name is zero.</div>
<div id="one">Number one, at your service.</div>
<div id="two">Howdy, I'm number two.</div>


</body>
</html>

coothead
12-22-2008, 02:42 PM
Hi there robkar97,

there is probably a 'proper' javascript solution to your problem but this is how I get round it...

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Content-Script-Type" content="text/javascript">

<script type="text/javascript">
if(window.addEventListener){
window.addEventListener('load',bindEvents,false);
}
else {
if(window.attachEvent){
window.attachEvent('onload',bindEvents);
}
}
function bindEvents(){
var elements=new Array('zero','one','two');
for(var i in elements) {
document.getElementById(elements[i]).className='a'+i;
document.getElementById(elements[i]).onclick = function(){
alert(this.className.split('a')[1])
}
}
}
</script>

</head>
<body>

<div id="zero">My name is zero.</div>
<div id="one">Number one, at your service.</div>
<div id="two">Howdy, I'm number two.</div>


</body>
</html>

tnowalk
12-22-2008, 02:56 PM
Like the other poster I do not know the proper work around, but I found this to work:


function bindEvents(){
var e = new Array('zero', 'one', 'two');
for (var i in e) { setAlert(e[i],i); };
}

function setAlert(e,i) {
document.getElementById(e).onclick = function() {alert(i);};
}


Best Regards,
Trevor

RysChwith
12-23-2008, 08:24 AM
Your problem has something to do with closures.

When you're declaring the onclick functions for the divs, you're not setting them to alert the value of i; you're setting them to alert the variable i itself. The variable i goes through its iterations and stops at 2.

The closure you've created prevents the variable from being destroyed, since there are still references to it. When the onclicks fire, they alert the current value of the variable i, which will always be 2 after your loop has executed.

As to how you would avoid it... I'm not entirely sure. Closures continue to confuse me at least a little.

Rys

robkar97
12-23-2008, 09:23 AM
Thanks for the very nice explanation, I think I am on the right track now (using a combination of the first two answers too).

I sometimes use "this=i" to store the value of i in a property of a specific object, but that doesn't work when "i" is an Object (I think...).

Anyway, problem solved. Thanks.

¥åßßå
12-23-2008, 10:57 AM
document.getElementById(elements[i]).onclick = function(){alert(this.id);}

¥