dynamic onclick problem

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • theS70RM
    New Member
    • Jul 2007
    • 107

    dynamic onclick problem

    Hi Guys,

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

    Heres the code:

    Code:
    <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;
    		
    		var otherDiv = itemDiv;
    		itemDiv.onclick = function(){alert(otherDiv.id);}
    		document.body.appendChild(itemDiv);
    	}
    
    }
    </script>
    
    </head>
    <body onload="initialise();">
    body text.
    </body>
    </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
  • gits
    Recognized Expert Moderator Expert
    • May 2007
    • 5390

    #2
    use the following 'explicit' closure construct:

    [CODE=javascript]itemDiv.onclick = function(param) {
    return function() { alert(param); };
    }(otherDiv.id);[/CODE]
    kind regards

    Comment

    • theS70RM
      New Member
      • Jul 2007
      • 107

      #3
      sorry i dont really understand how this works.

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

      Thanks

      Andy

      Comment

      • gits
        Recognized Expert Moderator Expert
        • May 2007
        • 5390

        #4
        just put it where you assign your onclick event ... it just replaces that ...

        kind regards

        Comment

        • hkma08
          New Member
          • Mar 2008
          • 11

          #5
          [HTML]<html>
          <head>
          <script language="javas cript">
          function initialise(){
          data = {"item 1" : "a","item 2" : "b", "item 3" : "c"};
          for (key in data)
          {
          itemDiv = document.create Element("DIV");
          itemDiv.innerHT ML = key;
          itemDiv.id = key;
          itemDiv.onclick = function(){aler t(this.id);}
          document.body.a ppendChild(item Div);
          }
          }
          </script>
          </head>

          <body onload="initial ise();">
          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?
          Last edited by gits; Mar 26 '08, 08:52 AM. Reason: added code tags

          Comment

          • theS70RM
            New Member
            • Jul 2007
            • 107

            #6
            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

            Comment

            • gits
              Recognized Expert Moderator Expert
              • May 2007
              • 5390

              #7
              Originally posted by hkma08
              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

              Comment

              Working...