www.webdeveloper.com
Results 1 to 9 of 9

Thread: adding onclick with createElement

  1. #1
    Join Date
    Mar 2010
    Posts
    11

    adding onclick with createElement

    This is driving me insane. I'm trying to use createElement inside a loop to make some <divs>, each of which has an onclick event. I threw together this test page to demonstrate it:

    Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Untitled Document</title>
    
    <style type="text/css">
    
    .btn
    {
    	width:100px;
    	height:50px;
    	background-color:#eeeeee;
    	border:1px solid black;
    	margin-bottom:10px;
    }
    </style>
    
    <script language="javascript">
    function test()
    {
    	for(var x=0;x<5;x++)
    	{
    		yay=document.createElement('div')
    		yay.className="btn"
    		
    		yay.id='yay'+x
    		
    		yay.innerHTML='lorem'
    		
    		yay.onclick=function(){alert(x)}
    		document.body.appendChild(yay)
    	}
    }
    </script>
    
    </head>
    
    <body onload="test()">
    
    
    
    </body>
    </html>
    When I click on any of the boxes it alerts "5", the final value of x after the loop ends, instead of what the value of x was when the loop executed and created the element ("0", "1", "2", etc.). This is happening if FF and ie.

    I also noticed in Firebug if I put a breakpoint on the "yay.onclick=function(){alert(x)}" line that it will break everytime I click on one of the boxes. Very strange...

    How can I put in a variable on the yay.onclick=function(){alert(x)} line and have it "stick"? Thanks!

  2. #2
    Join Date
    Apr 2003
    Location
    Netherlands
    Posts
    21,654
    Simplest:
    Code:
    yay.count=x;
    yay.onclick=function(){alert(this.count)}
    or retrieve it from the id value
    At least 98% of internet users' DNA is identical to that of chimpanzees

  3. #3
    Join Date
    Mar 2010
    Posts
    11
    Thanks, it worked. Although it seems really wierd that it works like that.

  4. #4
    Join Date
    Dec 2003
    Location
    Bucharest, ROMANIA
    Posts
    15,428
    Quote Originally Posted by raphael75 View Post
    Thanks, it worked. Although it seems really wierd that it works like that.
    What's so weird? Without "sticking" it as property of the object, the x variable will always have the last value after the loop is over. A primitive can not have multiple values.

  5. #5
    Join Date
    Mar 2010
    Posts
    11
    But each one of those divs is a different object. At the time they're being created x has a different value each time through the loop so I don't see why it wouldn't keep that value. How is it different from doing it this way:

    <div onclick="alert('1')" class="btn>...</div>

    <div onclick="alert('2')" class="btn>...</div>

    <div onclick="alert('3')" class="btn>...</div>

    etc.

    It's not a huge issue because I was able to create the "custom" attribute which holds the value of x.

  6. #6
    Join Date
    Apr 2003
    Location
    Netherlands
    Posts
    21,654
    Your original script does this:
    Code:
    <div onclick="alert(x)" class="btn>...</div>
    <div onclick="alert(x)" class="btn>...</div>
    <div onclick="alert(x)" class="btn>...</div>
    The JavaScript function is bound at runtime (onclick), not at creation (the loop). The value of 'x' is it's value at loop termination.
    At least 98% of internet users' DNA is identical to that of chimpanzees

  7. #7
    Join Date
    Aug 2014
    Posts
    1
    Quote Originally Posted by Fang View Post
    Your original script does this:
    Code:
    <div onclick="alert(x)" class="btn>...</div>
    <div onclick="alert(x)" class="btn>...</div>
    <div onclick="alert(x)" class="btn>...</div>
    The JavaScript function is bound at runtime (onclick), not at creation (the loop). The value of 'x' is it's value at loop termination.
    Allright so you more or less explained this behavior which no doubt confuses many people, BUT you did not propose any simple solution. How can we set an onclick property to a newly created DOM element so it remembers the actual VALUE in time of setting and not the variable name? That would be great. Thanks

  8. #8
    Join Date
    Mar 2007
    Location
    localhost
    Posts
    2,360
    You could...

    Code:
    yay.onclick=function(){alert(x)}
    change to

    Code:
    yay.onclick=function(){alert(parseInt( this.id ))}
    Yes, I know I'm about as subtle as being hit by a bus..(\\.\ Aug08)
    Yep... I say it like I see it, even if it is like a baseball bat in the nutz... (\\.\ Aug08)
    I want to leave this world the same way I came into it, Screaming, Incontinent & No memory!
    I laughed that hard I burst my colostomy bag... (\\.\ May03)
    Life for some is like a car accident... Mine is like a motorway pile up...

    Problems with Vista? :: Getting Cryptic wid it. :: The 'C' word! :: Whois?

  9. #9
    Join Date
    Jun 2004
    Location
    Portsmouth UK
    Posts
    2,683
    Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Untitled Document</title>
    
    <style type="text/css">
    
    .btn
    {
    	width:100px;
    	height:50px;
    	background-color:#eeeeee;
    	border:1px solid black;
    	margin-bottom:10px;
    }
    </style>
    
    <script language="javascript">
    function test()
    {
    	for(var x=0;x<5;x++)
    	{
    		yay=document.createElement('div')
    		yay.className="btn"
    
    		yay.id='yay'+x
    
    		yay.innerHTML='lorem'
    
    		document.body.appendChild(yay)
            addevt(yay,'click',clickme,x);
    	}
    }
    
    function clickme(x)
    {
    alert(x);
    }
    
    function addevt(o,t,f,p){
      o.addEventListener?o.addEventListener(t,function(e){ return f(p);},false):o.attachEvent?o.attachEvent('on'+t,function(e){ return f(p); }):null;
    }
    
    </script>
    
    </head>
    
    <body onload="test()">
    
    
    
    </body>
    </html>
    or

    Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Untitled Document</title>
    
    <style type="text/css">
    
    .btn
    {
    	width:100px;
    	height:50px;
    	background-color:#eeeeee;
    	border:1px solid black;
    	margin-bottom:10px;
    }
    </style>
    
    <script language="javascript">
    function test()
    {
    	for(var x=0;x<5;x++)
    	{
    		yay=document.createElement('div')
    		yay.className="btn"
    
    		yay.id='yay'+x
    
    		yay.innerHTML='lorem'
    
    		document.body.appendChild(yay)
            clickme(yay,x);
    	}
    }
    
    function clickme(o,x)
    {
     o.onclick=function(){ alert(x); }
    }
    
    
    </script>
    
    </head>
    
    <body onload="test()">
    
    
    
    </body>
    </html>
    Last edited by vwphillips; 08-31-2014 at 09:00 AM.
    Vic

    God loves you and will never love you less.

    http://www.vicsjavascripts.org/Home.htm
    If my post has been useful please donate to http://www.operationsmile.org.uk/

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center



Recent Articles