469,357 Members | 1,834 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,357 developers. It's quick & easy.

dynamic onclick problem

107 100+
Hi Guys,

Im trying to create lots of divs all with there own onclick event...

Heres the code:

Expand|Select|Wrap|Line Numbers
  1. <html>
  2. <head>
  3. <script language="javascript">
  4.  
  5. function initialise(){
  6.     data = {"item 1" : "a","item 2" : "b", "item 3" : "c"};
  7.  
  8.     for (key in data)
  9.     {
  10.         itemDiv = document.createElement("DIV");
  11.         itemDiv.innerHTML = key;
  12.         itemDiv.id = key;
  13.  
  14.         var otherDiv = itemDiv;
  15.         itemDiv.onclick = function(){alert(otherDiv.id);}
  16.         document.body.appendChild(itemDiv);
  17.     }
  18.  
  19. }
  20. </script>
  21.  
  22. </head>
  23. <body onload="initialise();">
  24. body text.
  25. </body>
  26. </html>

Seems like no matter what way i do it the onclick events all end up being the same as whichever one was created last.

I put the var otherDiv = itemDiv; line in to try and change this, but its still the same.

Can anyone help??


Cheers

Andy
Mar 20 '08 #1
6 1498
gits
5,390 Expert Mod 4TB
use the following 'explicit' closure construct:

Expand|Select|Wrap|Line Numbers
  1. itemDiv.onclick = function(param) {
  2.     return function() { alert(param); };
  3. }(otherDiv.id);
kind regards
Mar 20 '08 #2
theS70RM
107 100+
sorry i dont really understand how this works.

can you sub it into my posted code so the example works.

Thanks

Andy
Mar 25 '08 #3
gits
5,390 Expert Mod 4TB
just put it where you assign your onclick event ... it just replaces that ...

kind regards
Mar 25 '08 #4
hkma08
11
[HTML]<html>
<head>
<script language="javascript">
function initialise(){
data = {"item 1" : "a","item 2" : "b", "item 3" : "c"};
for (key in data)
{
itemDiv = document.createElement("DIV");
itemDiv.innerHTML = key;
itemDiv.id = key;
itemDiv.onclick = function(){alert(this.id);}
document.body.appendChild(itemDiv);
}
}
</script>
</head>

<body onload="initialise();">
body text.
</body></html>[/HTML]

Two logical reasons it doesn't work:
1. there is no use to state var otherDIv = itemDiv. This would just create another div element with empty content
2. most important is that, in each for loop steps, you used the same var (itemDiv), in first loop itemDiv = item 1, second loop itemDiv = item 2, last loop you set itemDiv = item 3. When all javascript finished, it use item 3 as variable and alert item3.id, that is why you always got item 3 as result. Instead, you can use this.id to refer to its own id when you click on an item.

Is this clear enough?
Mar 25 '08 #5
theS70RM
107 100+
Ah yes,

That does make it a bit clearer thanks.

I didnt understand that it was alerting the same variable for each one, i thought it would treat each one as a new instance.


Cheers


Andy
Mar 26 '08 #6
gits
5,390 Expert Mod 4TB
Two logical reasons it doesn't work:
1. there is no use to state var otherDIv = itemDiv. This would just create another div element with empty content
2. most important is that, in each for loop steps, you used the same var (itemDiv), in first loop itemDiv = item 1, second loop itemDiv = item 2, last loop you set itemDiv = item 3. When all javascript finished, it use item 3 as variable and alert item3.id, that is why you always got item 3 as result. Instead, you can use this.id to refer to its own id when you click on an item.

Is this clear enough?
in for-loops you have to use closures for such assignments ... that is exactly what i showed you with the given example. as you can see it passes a reference to the function that is immediatly executed and the returned function stores that passed reference and alerts the correct id ...

the 'this-construct' should work too ... but sometimes you just need the loop-index or something that is not in the this-context of the current node in your handler function and then you need the closure ...

kind regards
Mar 26 '08 #7

Post your reply

Sign in to post your reply or Sign up for a free account.

Similar topics

3 posts views Thread by Aaron Gervais | last post: by
1 post views Thread by kusanagihk | last post: by
1 post views Thread by comicgeekspeak | last post: by
1 post views Thread by CARIGAR | last post: by
reply views Thread by suresh191 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.